1. 程式人生 > >C++動態聯編的好處,為什麼要用基類的指標指向派生類的方式來實現重寫

C++動態聯編的好處,為什麼要用基類的指標指向派生類的方式來實現重寫

動態聯編的意義:省事
一個derived類物件,要呼叫一個函式,他就會在自己的類中查詢函式名,如果找到了就呼叫自己的;
如果沒找到就到基類找,呼叫基類的函式。(名字查詢優先於型別檢查,找到名字符合的就停下來,不向上一個基類的作用域繼續找)。

class A
{
public:
    virtual void fun()      //1
    {
        std::cout << "this is A " << std::endl;
    }
};


class B : public  A
{
public:
    void fun()      
    {
        std
::cout << "this is B " << std::endl; } /* void fun(int a) // 2 { std::cout << "this is B " << std::endl; } */ }; int main(int argc, const char* argv[]) { A a; B b; a.fun(); b.fun(); return 0; }

上面的函式執行起來沒問題,結果

this is A
this
is B

但是,如果把B類裡的函式加上引數,即上面程式碼塊的 2 號 函式。此時,執行b.fun( ); 按理應當執行基類A的fun(),因為B的fun()引數和呼叫不符合,但是這段程式碼編譯會報錯error: no matching function for call to ‘B::fun()’,,編譯器找不到匹配的函式。即,名字查詢優先於型別檢查,找到名字符合的就停下來,不向上一個基類的作用域繼續查詢。這就是同名隱藏。

為什麼要用指標或引用:
1、指標或者引用操作時,派生類的虛表會被給過去(這才是重點),這個指標就能按照這個虛表呼叫虛擬函式。
2、預設的賦值運算子並不會操作虛擬函式表。所以要實現多型,必須使用指標或者引用。

為什麼要用基類指向派生類這種方式:
為了跳過同名隱藏這一道坎,使用基類指標變成呼叫虛擬函式變成從上往下找;

class A
{
public:
    virtual void fun()
    {
        std::cout << "this is A " << std::endl;
    }
};


class B : public  A
{
public:
    void fun(int a)
    {
        std::cout << "this is B " << std::endl;
    }
};


class C : public B
{
public:
    void fun ()
    {
        std::cout << "this is C " << std::endl;
    }
};

int main(int argc, const char* argv[])
{
    A* Pb = new B;
    A* Pc = new C;
    Pb->fun();
    Pc->fun();
    return 0;
}                                              

輸出結果:

this is A
this is C

可以看到,A*型別的指標指向了B,但是執行的卻是A的函式。

相關推薦

指標指向派生物件

基類指標指向派生類物件 3種情況: 一般只能呼叫基類的函式 呼叫的函式,在基類中函式如果是虛擬函式,呼叫繼承類的函式 呼叫的函式,在基類中函式如果只在繼承類中有,報錯 然後來看一組程式碼例項: #include <iostream> usi

C++動態的好處為什麼指標指向派生方式實現重寫

動態聯編的意義:省事 一個derived類物件,要呼叫一個函式,他就會在自己的類中查詢函式名,如果找到了就呼叫自己的; 如果沒找到就到基類找,呼叫基類的函式。(名字查詢優先於型別檢查,找到名字符合的就停下來,不向上一個基類的作用域繼續找)。 class

c++動態與靜態

摘要】:本文闡述了靜態聯編和動態聯編的概念和區別,通過具體例項分析了實現動態聯編的條件,指出了虛擬函式是實現動態聯編的基礎。 【關鍵詞】:靜態聯編;動態聯編;虛擬函式 在C++中,聯編是指一個計算機程式的不同部分彼此

c++動態和靜態

將一個呼叫函式者聯結上正確的被呼叫函式,這過程叫做函式聯編。c++中的聯編分兩種,分為靜態聯編和動態聯編。 為加virtual時是靜態聯編;加入virtual是動態聯編。只有在使用指標或者引用時,才能實現在執行時的動態聯編。 #include<io

C++ 指標派生指標之間的轉換

函式過載、函式隱藏、函式覆蓋 函式過載只會發生在同作用域中(或同一個類中),函式名稱相同,但引數型別或引數個數不同。 函式過載不能通過函式的返回型別來區分,因為在函式返回之前我們並不知道函式的返回型別。 函式隱藏和函式覆蓋只會發生在基類和派生類之間。 函式隱藏是指派

c++父指標指向物件

c++父類指標指向子類物件   父類子類指標函式呼叫注意事項 1,如果以一個基礎類指標指向一個衍生類物件(派生類物件),那麼經由該指標只能訪問基礎類定義的函式(靜態聯翩) 2,如果以一個衍生類指標指向一個基礎類物件,必須先做強制轉型動作(explicit cast),這種做法很

關於C++的子指標指向

  1,直接用基類指標引用基類物件2,直接用派生類指標引用派生類物件3,用基類指標引用一個派生類物件,由於派生類物件也是基類的物件,所以這種引用是安全的,但是隻能引用基類成員。若試圖通過基類指標引用那些只在派生類中才有的成員,編譯器會報告語法錯誤。(解決該問題的答案是虛擬函式和多型性)4

C++學習筆記】父指標指向物件

        虛擬函式的作用主要是實現了多型的機制。簡而言之就是用父型別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。但僅僅可呼叫父類含有的函式,非父類函式不能呼叫。 普通虛擬函式呼叫 假設我們有下面的類層次: #includ

C++深度解析 多型的概念和意義 --- virtual虛擬函式靜態動態

C++深度解析 多型的概念和意義 --- virtual,虛擬函式,靜態聯編,動態聯編       多型 通過使用virtual關鍵字對多型進行支援 示例程式: #include <iostream> #include <s

《隨筆八》—— C++中的“ 多型中的靜態動態

目錄          多型 在編譯時的靜態聯編 在執行時的靜態聯編 在編譯時的動態聯編 在執行時的動態聯編 下面先給出一些程式碼示例,引用出要使用多型的原因: class Persion { public:

C++中的虛擬函式與靜態動態

          程式在呼叫函式時,將使用哪個可執行程式碼塊呢?編譯器負責回答這個問題,將原始碼中的函式呼叫解釋為執行特定的函式程式碼塊被稱為函式名聯編。在C中,因為每個函式名都對應一個不同的函式,而在C++中,由於函式過載的緣故,編譯器必須檢視函式引數以及函式名才能確定

C++基礎---靜態動態

1. 靜態聯編與動態聯編 1.1 函式聯編的定義 函式聯編:將一個呼叫函式者聯結上正確的被呼叫函式的過程,一般稱為聯編。 C++中的聯編分兩種: (1)靜態聯編; (2)動態聯編;

C++ 靜態動態

靜態聯編和動態聯編 1、聯編是指一個程式模組、程式碼之間互相關聯的過程。 2、靜態聯編(static binding),是程式的匹配、連線在編譯階段實現,也稱為早期匹配。 過載函式使用靜態

C++的靜態動態技術

聯編是指一個計算機程式自身彼此關聯的過程。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。 靜態聯編 靜態聯編是指聯編工作出現在編譯連線階段,這種聯編又稱早期聯編,因為這種聯編過程是在程式開始執行之前完成的。 在編譯時所進行的這種聯編又稱靜態束定。在編

C++之靜態動態及virtual關鍵字的作用

定義 將一個呼叫函式連線上正確的被呼叫函式,這個過程就叫做函式的聯編,簡稱聯編。在C++中,一共有兩種聯編的方式:靜態聯編 #define:靜態聯編是指聯編工作出現在編譯連線階段。 特點:① 靜態聯編就是指被呼叫函式和執行呼叫函式之間的關係以及它們在記憶體中的地址在編譯的

C# 動態生成WebService無需添加引用

color csharp import exception 客戶 pri [] return encoding C#項目調用WebService是很常見的現象,但一旦修改鏈接地址就需要重新更新引用很是麻煩,這裏跟大家分享一個通過地址,無需添加引用動態生成Webservice

c++動態庫封裝及調(1、動態庫介紹)

oca 新版本 指令 二進制 運行時 失去 理論 load 程序 1、一個程序從源文件編譯生成可執行文件的步驟: 預編譯 --> 編譯 --> 匯編 --> 鏈接 (1)預編譯,即預處理,主要處理在源代碼文件中以“#”開始的預編譯指令,如宏展開、處理條

YY李學淩的野心區塊鏈技術改變傳統信息的傳輸路徑

出席 每一個 很多 未來 認知 自動生成 生產 2017年 本地 7月22日,歡聚時代董事長李學淩出席某科技商業峰會並發表演講,演講中,李學淩對外展示了一款基於區塊鏈技術的即時通訊應用BCM。 李學淩在演講中透露出來幾個重要的信息。一是歡聚時代很重視區塊鏈技術應用,二是歡聚

c/c++ 網絡程 UDP if_nameindex和ioctl取得主機網絡信息

soc n-2 技術分享 ram ddr con ioc alt lis 網絡編程 UDP 用if_nameindex和ioctl取得主機網絡信息 getifaddrs函數取得的東西太多了,如果只想取得網卡名字和網卡編號可以用下面的2個函數。 1,if_nameindex

java小數運算內附現成的工具。不能double和floatdecimal

https://www.cnblogs.com/xujishou/p/7491932.h 為什麼會出現這個問題呢,就這是java和其它計算機語言都會出現的問題,下面我們分析一下為什麼會出現這個問題: float和double型別主要是為了科學計算和工程計算而設計的。他們執行二進位制浮點運算,這是