2013-03-21 23 views
2

我在想這可能是一個重複的問題,但我嘗試閱讀幾乎所有相關的帖子,但它們都不是特定於什麼我在找。調用派生類函數而不將它標記爲多級繼承中的一個類的虛擬

好吧,我明白你不能從基類指針調用派生類中的函數,除非它被標記爲虛擬。就像在參考程序1中一樣,如果WhichClass()沒有標記爲虛擬的,它就不能調用B類的WhichClass()。

#include<iostream> 
using namespace std; 
class A 
{ 
    public: 
    const char* WhichClass(){return "A";} 
}; 
class B:public A 
{ 
    public: 
    const char* WhichClass(){return "B";} 
}; 

int main() 
{ 
    B b; 
    A &a = b; 
    cout<<"In class "<<a.WhichClass(); 
    return 0; 
} 

如果我將它標記爲虛擬的,那麼它會從基類中調用大多數派生類的函數。現在假設我添加了另一個從B繼承的類C(如程序2所示),並且如果在類B中WhichClass()未標記爲虛擬,那麼基類引用(&a)如何在Class中調用WhichClass()函數C?還有B類參考文獻(& b),當我們在程序1中觀察到它甚至沒有在B類中標記爲虛擬時,它如何在C中調用WhichClass()?

#include<iostream> 
using namespace std; 
class A 
{ 
    public: 
    virtual const char* WhichClass(){return "A";} 
}; 
class B:public A 
{ 
    public: 
    const char* WhichClass(){return "B";} 
}; 
class C:public B 
{ 
    public: 
    const char* WhichClass() { return "C";} 
}; 
int main() 
{ 
    C c; 
    A &a = c; 
    B &b = c; 

    cout<<"In class " << a.WhichClass() << endl; 
    cout<<"In class " << b.WhichClass() << endl; 
    return 0; 
} 

回答

2

因爲當你犯了一個方法在基類中的虛擬並創建一個基類指針指向任何派生類,那麼在這種情況下,它會調用最派生類的功能。 你的情況,你有,

A &a = c; 

這裏基類的指針指向C類,所以當你調用WhichClass()方法將C類的方法被調用。

B &b = c; 

即使在這裏也當您使用基類指針調用一個函數,最派生類的功能是基於您指向哪個類調用。在這種情況下,類B的指針指向類C的對象,因此類C的WhichClass()方法將被調用。 有關詳細信息,請查看本,polymorphism

+1

謝謝,只是確認了第一例。但在第二個函數中,函數沒有被標記爲虛擬的,它是如何知道它應該調用C類的WhichClass()? IMO,B類中的v表項指向B :: WhichClass(),因爲它不是虛擬的。沒有? – 2013-03-21 05:16:11

+2

但是B繼承自A,其中函數被標記爲虛擬的,所以A具有用於其虛擬函數的vtable條目,當A被任何其他類繼承時,另一個vtable被創建用於使類派生函數虛擬的類。 – shofee 2013-03-21 05:19:03

2
  1. 在一類鏈,如果你在聲明基類的一些功能virtual具有相同的定義所有的波紋管一級派生類的功能會自動將virtual
  2. 根據重寫的功能選擇背後的場景,由概念調用virtual table完成。所以如果你對此感興趣,請閱讀here
  3. 在C++ 11中,你可以使用final關鍵字來停止在某個級別的覆蓋。 (例如:如果你想避免類'C'來覆蓋類'B的WhichClass函數)。檢查here
相關問題