2013-03-20 67 views

回答

2

TL; DR

利用在C++多態性的唯一方法是通過虛函數和指針(和參考文獻)。 virtual關鍵字將告訴編譯器在處理指向具有子類的動態類型的基類的指針時決定調用何種版本的虛函數時,分配一個虛函數表。

如何在C多態性工作++

讓我們舉一個簡單的例子:

class A { public: virtual void eat() { std::cout << "Class A" << std::endl; } 
class B : public A {}; 
class C : public B { virtual void eat() { std::cout << "Class C" << std::endl; } 

注:虛擬關鍵字可以在第一函數/方法定義之後被省略。

以下:

A a; B b; C c; 
A* ptrA = &a; A* ptrB = &b; A* ptrC = &c; 
ptrA->eat(); 
ptrB->eat(); 
ptrC->eat(); 

會打印:

Class A 
Class A 
Class C 

如果我們就不會宣佈功能eat虛擬,輸出會被簡單:

Class A 
Class A 
Class A 
+0

感謝這個明確的例子! – user1824518 2013-03-20 04:02:27

3

區別在於何時有基準或指向基類的指針。對虛函數的調用將調用派生最多的版本,而對普通函數的調用將調用基類版本。

如果您直接使用變量或引用或指向最派生類的指針,則沒有實際區別。

4

一個例子最好說它:

#include <iostream> 

using namespace std; 

class A { 
public: 
    virtual void f1() { cout << "Class A" << endl; } 
    void f2() { cout << "Class A" << endl; } 
    virtual ~A(){} 
}; 

class B : public A { 
public: 
    virtual void f1() { cout << "Class B" << endl; } 
    void f2() { cout << "Class B" << endl; } 
    virtual ~B(){} 
}; 

int main() 
{ 
    A *a = new B; 
    a->f1(); 
    a->f2(); 
} 

...

$ ./override 
Class B 
Class A 

你可以看到,當我們引用B的情況下,f1()還叫B的版本,但f2()電話A's。

當你聲明一個虛函數時,你說當我們調用它時,我們應該使用vtable來查找要調用的函數的正確版本,所以你將永遠得到該函數的最衍生版本,即使你將它作爲祖先類型引用。如果沒有虛擬,它將簡單地使用您引用它的類型中的定義。

相關問題