1. 程式人生 > >C++(多型實現原理)函式重寫,過載,重定義

C++(多型實現原理)函式重寫,過載,重定義

多型的實現原理:

         首先介紹下函式重寫 重定義 過載的區別;

函式重寫

         發生在父類和子類之間,子類將父類中的同名函式進行了覆蓋,如果在函式前面含有virtual那麼就是重寫,如果沒有就成了覆蓋,子類的同名函式將會覆蓋(隱藏)父類的同名函式,如果想呼叫的話,那麼就要使用::作用域運算子

函式過載

         函式過載發生在同類之間,平等關係。在不同的類對函式看似過載的操作是不成立的

多型理論基礎:

         靜態聯編:

         是程式的匹配,連線在編譯階段實現,也成為早起匹配,過載使用的就是靜態聯編

動態聯編譯:

         是指程式聯編推遲到執行時進行,又成為遲繫結

在編譯階段,編譯器自動根據指標的型別判斷是執行的父類物件還是子類物件:出於程式安全的角度講,編譯器認為父類指標指向父類物件,子類指標指向子類物件。這就是靜態聯編的結果

(一)談談你對多型的理解?

答:

1.      多型的實現效果,同樣的呼叫語句有不同的表現形態:

2.      多型實現有三個條件?

有繼承,有虛擬函式重寫,有父類指標指向子類物件:

3.      Virtual關鍵字告訴編譯器這個函式支援多型,不要根據指標的型別進行呼叫,而是根據指標所指向的具體的物件,進行函式呼叫

4.      理論基礎:

動態聯編PK靜態聯編,根據實際的物件的型別來判斷重寫函式的呼叫

5.      多型的重要意義:

設計模式的基礎,是程式碼框架的基石

(二)是否每個類的成員函式都宣告為虛擬函式,為什麼??

答.可以宣告為虛擬函式,但是在在定義物件的時候,會生成一個虛擬函式表,而虛擬函式在呼叫的時候是通過定址實現的,這回影響程式碼的執行效率

(三)建構函式中呼叫虛擬函式能實現多型嗎?

答.不可以,因為多型的vptr指標是分佈初始化的,在子類進行初始化的時候先呼叫父類的建構函式,這時候子類的父類的Vptr指標都是指向父類的,因此產生不了多型。

(四)為什麼要定義虛解構函式?

答.因為virtual可以指引delete運算子正確析構動態物件

是這樣的,當發生多型的時候,基類指標指向派生類,當釋放記憶體的時候,編譯器根據指標型別去呼叫相應的函式,由於是基類指標,那麼只會去呼叫基類物件的析構

函式,從而導致發生多型的子類物件的解構函式不能正常執行,但是當宣告為虛析構的時候就能正常使用了,父類解構函式virtual,子類進行重寫,那麼就可以正常的進行析構了。

(五)重點:

         就是基類指標指向父類物件還是子類物件???我們在分析的時候是這麼分析的,如果基類指標指向父類物件,那麼就去呼叫父類的物件;如果指向子類物件,就去呼叫子類物件。

  靜態聯編:是編譯根據指標型別進行物件的確定;   動態聯編譯是根據,指標指向的物件進行函式呼叫,(要含有虛擬函式,如果沒有虛擬函式是不是要報錯(所以產生了dynamic_cast< >這個東東進行執行時型別檢查))

但是實際情況是這樣的,編譯器壓根就不是這麼做的。而是根據傳遞來的是什麼物件,然後看此函式是否是虛擬函式,如果是虛擬函式,就去找這個物件對應的虛擬函式表,然後呼叫相應的函式。

實現了過載或重寫的函式,如果想在子類中呼叫父類的函式,那麼可以使用(類名::函式名 ) 的方式來訪問父類中的函式

#include<iostream>
using namespace std;
class AA{
public:
    int add(int a,int b){
        return a + b;
    }
    virtual int sub(int a,int b){
        return a - b;
    }
};
class BB :public AA{
public:
    int add(int a, int b){
        return a + b +10;
    }
    virtual int sub(int a, int b){
        return a - b -10;
    }
};
void main(){
    int a = 100, b = 100;
    /*函式過載*/
    BB bb;
    AA aa;
    int c = aa.add(a, b);//200
    cout << c  << endl;
    c = bb.add(a, b);//210
    cout << c << endl;
    c = bb.AA::add(a, b);//200
    cout << c << endl;
    /*函式重寫*/
    c = bb.sub(a, b);//-10
    cout << c << endl;
    c = bb.AA::sub(a, b);//0
    cout << c << endl;
    system("pause");
}

相關推薦

C++(實現原理)函式重寫過載定義

多型的實現原理:          首先介紹下函式重寫 重定義 過載的區別; 函式重寫:          發生在父類和子類之間,子類將父類中的同名函式進行了覆蓋,如果在函式前面含有virtual那麼就是重寫,如果沒有就成了覆蓋,子類的同名函式將會覆蓋(隱藏)父類的同名

淺談C++實現原理(虛繼承的奧祕)

大夥都知道,如果要實現C++的多型,那麼,基類中相應的函式必須被宣告為虛擬函式(或純虛擬函式)。舉個例子: class Point { public: Point(float x = 0.0, float y = 0.0) : _x(x), _y(y) { } virtual fl

c++原理 以及虛擬函式表詳解

c++中多型的原理 要實現多型,必然在背後有自己的實現機制,如果不瞭解其背後的機制,就很難對其有更深的理解。 一個多型的例子 class Person{ public: virtual void Drink() { cout << "drink water" &

C++實現原理

理論知識: 當類中宣告虛擬函式時,編譯器會在類中生成一個虛擬函式表。 虛擬函式表是一個儲存類成員函式指標的資料結構。 虛擬函式表是由編譯器自動生成與維護的。 virtual成員函式會被編譯器放入虛擬函式表中。 當存在虛擬函式時,每個物件中都有一個指向虛擬函式表的指標

c++實現原理

c++編譯器 anim 被調用 虛指針 編譯 基類 綁定 確定調用 包括 C++的多態性用一句話概括就是:在基類的函數前加上virtual關鍵字,在派生類中重寫該函數,運行時將會根據對象的實際類型來調用相應的函數。如果對象類型是派生類,就調用派生類的函數;如果對象類型是基類

反射和實現原理詳解

Table of Contents 反射和多型 多型 多型的定義和用法 多型的實現原理 反射 反射的實現原理 反射的應用 反射的弊端 反射和多型 這兩種技術並無直接聯絡,之所以把它們放在一起說,是因為Java提供讓我們在執行時識別物件和類的資訊,主要有

C++原理

在講原理之前,首先介紹靜態聯編和動態聯編: 靜態聯編:再編譯階段確定程式執行的程式碼,比如普通的變數定義int a = 10,以及函式過載等 動態聯編:在程式執行過程中確定程式執行的程式碼,比如條件判斷語句 多型的原理: 當一個類具有虛擬函式時,編譯器會自動為這個類在全域性區中的常量區新增一個虛擬函式

C++ 與虛擬函式

多型按字面的意思就是多種形態。當類之間存在層次結構,並且類之間是通過繼承關聯時,就會用到多型。C++ 多型意味著呼叫成員函式時,會根據呼叫函式的物件的型別來執行不同的函式。下面的例項中,基類 Shape 被派生為兩個類,如下所示: #include <iostream> usin

C++學習筆記 (六) ---- C++與虛擬函式

①、多型的概念 先上一個示例 #include <iostream> using namespace std; //基類People class People{ public: People(char *name, int age); voi

實現原理剖析

1. 虛擬函式表 C++的多型是通過一張虛擬函式表(virtual Table)來實現的,簡稱為V-Table,(這個表是隱式的,不需要關心其生成與釋放)在這個表中,主要是一個類的虛擬函式的地址表,這張表解決了繼承,覆寫的問題,保證其真實反應實際的函式,這樣,在有虛擬函式的類的例項中這個表被分配在了這個例項

淺析實現原理

實現過程 當我們在宣告一個類時,編譯器會自動幫我們建立一個虛擬函式表。 比如下面的這段程式碼: 編譯器為我們生成的虛擬函式表 虛擬函式表: 虛擬函式表是由編譯器自動產生的一種儲存類成員函式的一種資料結構。其中虛擬函式會被自動放入表中。 那編譯器是怎

C++ 與虛擬函式

多型是指使用相同的函式名來訪問函式不同的實現方法,即“一種介面,多種方法”,用相同的形式訪問一組通用的運算,每個運算可能對應的行為不同。 C++支援編譯時多型和執行時多型,運算子過載和函式過載就是編譯時多型,而派生類和虛擬函式實現執行時多型。 執行時多型的基礎是基類指標,基

C++什麼、覆蓋、重寫過載剖析_boomgo

首先說下多型、覆蓋、重寫、過載、隱藏其實沒那麼複雜,就只有三種,過載算一種,還有一種 就是覆蓋(也稱之為重寫),剩下那種最後說。 覆蓋是具有virtual,概念就不說了。覆蓋就是多型的具體體現。不忘初心,方的始終,首先說說 為什麼要多型,多型作用是什麼呢?多型的作用就是介

重寫過載定義

(1)重寫(override):重寫也可以看做覆蓋,子類重新定義父類中具有相同名稱和引數的虛擬函式,函式特徵相同,但函式的具體實現不同,它主要在繼承關係中出現。被重寫的函式不能是static的,但必須是virtual的。 (2)過載(overload):過載是函式名相同,引

重寫過載定義的區別

重寫(override) 首先,重寫是指派生類的方法覆蓋基類的方法,要求方法名、方法的引數都相同。重寫是C++中實現多型這個特性基礎。重寫又稱為覆蓋,是指派生類函式覆蓋基類函式,與重定義不同,重寫要求被重寫的基類函式為虛擬函式。 例如下面的程式碼

C++呼叫實現原理(虛擬函式表詳解)

1.帶有虛擬函式的基類物件模型 我們先看段程式碼: #include<iostream> using namespace std; class B1 { public: void func1() {} int _b; }; class B2 { pub

c++語言虛擬函式實現原理

 自上一個帖子之間跳過了一篇總結性的帖子,之後再發,今天主要研究了c++語言當中虛擬函式對多型的實現,感嘆於c++設計者的精妙絕倫 c++中虛擬函式表的作用主要是實現了多型的機制。首先先解釋一下多型的概念,多型是c++的特點之一,關於多型,簡而言之就是 用父類的指標指向其子類的例項,然後通過父類的

虛擬函式表-C++實現原理

[toc] 參考:http://c.biancheng.net/view/267.html # 1、說明 我們都知道多型指的是父類的指標在執行中指向子類,那麼它的實現原理是什麼呢?答案是虛擬函式表 在 ***關於virtual*** 一文中,我們詳細瞭解了C++多型的使用方式,我們知道沒有 ***vi

C++虛擬函式虛擬函式純虛擬函式

1、多型性   指相同物件收到不同訊息或不同物件收到相同訊息時產生不同的實現動作。   C++支援兩種多型性:編譯時多型性,執行時多型性。    a、編譯時多型性:通過過載函式實現 ,模板(2次編譯)   b、執行時多型性:通過

C#(虛方法抽象介面實現

轉自   淺談C# 多型的魅力(虛方法,抽象,介面實現) 前言:我們都知道面向物件的三大特性:封裝,繼承,多型。封裝和繼承對於初學者而言比較好理解,但要理解多型,尤其是深入理解,初學者往往存在有很多困惑,為什麼這樣就可以?有時候感覺很不可思