簡體   English   中英

隱藏在派生類中的虛函數

[英]Virtual function hiding in derived class

我有兩個與繼承相關的類:

class Base
{
public:
    virtual void f(int x)
    {
        cout << "BASE::int" << endl;
    }
    virtual void f(double x)
    {
        cout << "BASE::double" << endl;
    }
};

class Derived : public Base
{
public:
    virtual void f(str::string s)
    {
        cout << "DERIVED::string" << endl;
    }
};

我在派生類中提供了具有不同參數的相同方法。 這意味着而不是覆蓋,我隱藏了此函數的基類版本。 因此,下面的電話是預期的,對我來說很清楚。

std::string str("Hello");
Base b;
b.f(1);        //calls base class version.
b.f(str);      //error.

Derived d;
d.f(1);        //error.
d.f(str);      //calls derived class version.

但是我無法澄清最后一種情況。

Base *b = new Derived;
b->f(str);     //results in error.

編譯器不會使用vtables和vptrs將此調用綁定到f的派生版本。 但是相反,它正在做其他事情。 誰能提供我完整的路徑,編譯器將如何嘗試按照語言機制解決此調用。

如果指針的類型為Base*則只能“查看”在Base類中定義的成員。 編譯器不會(或假裝不)“知道”該變量確實指向Derived的實例,即使您在上一行中僅為其分配了一個實例。

當您將變量聲明為Base*類型時,就是在告訴編譯器:將其視為可能指向Base或派生自其的任何類的東西。 因此,您無法訪問在特定派生類中定義的成員,因為無法保證指針實際上指向該派生類的實例。

vtable僅在運行時輸入圖片。 生成的程序集將查找函數的vptr值並跳轉到該地址。 這也意味着多態性被“限制”為Base知道的功能。 請注意,這也更有意義-類的定義應僅取決於自身及其父級。 如果您想讓Base* b知道Derived實現的虛函數,最終將根據Base的子級獲得Base的vtable條目數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM