簡體   English   中英

c ++多態,派生類的名稱解析

[英]c++ polymorphism, name resolution for derived class

class Base {
public:
virtual void f(float) { cout << "Base::f(float)\n"; }
};
class Derived : public Base {
public:
virtual void f(int) { cout << "Derived::f(int)\n"; }
};
int main() {
Derived *d = new Derived();
Base *b = d;
b->f(3.14F);
d->f(3.14F);
}

-C ++不支持contravaraint返回類型,因此f(int)不會覆蓋f(float)

-Polymorphism由C ++支持,因此d和b都應指向派生類的vtable。

派生類的-vtable類似於0:f(float),1:f(int)等。

我對這個問題的回答是Base :: f(float)被調用兩次,但答案是:

Base :: f(float)Derived :: f(int)

為什么會這樣? 從不同的指針訪問派生類是否強制執行某些規則? 據我所知,對象切片僅在使用copy-ctor或copy-assignment時發生,使用指針,它們都應指向相同的vtable。

不同類中的方法不會一起重載; Derived定義另一個f()可以防止在重載過程中考慮Base那個。

如果要添加新的重載而不隱藏基類中定義的重載,則需要將基本定義顯式引入派生類。

public:
    using Base::f;

我對此的看法是,當你調用d->f(3.14F) float隱式轉換為int

你的Derived類實際上有兩個f()項

void f(int);
void f(float);

使用帶有-fdump-class-hierarchy標志的g ++確認了這一點。 我們可以看到輸出如下:

Vtable for Base
Base::_ZTV4Base: 3u entries
0     (int (*)(...))0
4     (int (*)(...))(& _ZTI4Base)
8     (int (*)(...))Base::f

Vtable for Derived
Derived::_ZTV7Derived: 4u entries
0     (int (*)(...))0
4     (int (*)(...))(& _ZTI7Derived)
8     (int (*)(...))Base::f
12    (int (*)(...))Derived::f

由於定義不匹配, Derived類不會觸及基類中的f函數。 代碼編譯是因為float和int之間存在隱式轉換。

請嘗試以下方法

class Derived : public Base {
public:
virtual void f(std::string) { cout << "Derived::f(string)\n"; }
};

然后這段代碼將不會編譯為Derived:f(...)將隱藏Base :: f(...)定義。 這通常稱為繼承陰影。

因此調用b-> f(3.14F)將在Base表中解析,d-> f(3.14F)將使用Derived表解析,該表將影響Base。

暫無
暫無

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

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