2011-05-03 113 views
3

在C++中:覆蓋非虛函數和覆蓋虛函數有什麼區別?覆蓋非虛擬功能和虛擬功能有什麼區別?

+2

改寫裝置無關。你想問關於成員函數隱藏,覆蓋或重載嗎?如果你想澄清你的問題,在這裏搜索每一個。 – 2011-05-03 17:40:00

+0

如果沒有人提及它:請參考[The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)並給自己買一個關於C++的好書。 – 2011-05-03 17:42:00

回答

8

隨着virtual

class Base { 
    virtual void Foo() { std::cout << "Foo in Base" << std::endl;} 
}; 

class Derived : public Base { 
    virtual void Foo() { std::cout << "Foo in Derived" << std::endl;} 
}; 

// in main() 
Derived* d = new Derived(); 
d->Foo(); // prints "Foo in Derived" 

Base* b = new Derived(); 
b->Foo(); // prints "Foo in Derived" 

,並沒有(相同的代碼,但離開了virtual):

// in main() 
Derived* d = new Derived(); 
d->Foo(); // prints "Foo in Derived" 

Base* b = new Derived(); 
b->Foo(); // prints "Foo in Base" 

所以不同的是,沒有virtual,沒有真正運行時多態性:其函數的調用由編譯器決定,具體取決於調用它的指針/引用的當前類型。

隨着virtual,對象維護一個虛擬函數列表(vtable),其中它查找要調用的函數的實際地址 - 在運行時,每次調用它的虛擬成員時。在本示例中,Foo的條目由Derived構造函數隱式修改爲指向覆蓋的函數,因此Foo通過Base指針被調用並不重要。

0

覆蓋虛擬函數將確保在運行時評估對象的類型並調用適當的方法。

實施例:

class Vehicle 
{ 
public: 
    void PrintType(); // Prints "Vehicle" 
}; 

class Car: public Vehicle 
{ 
// overwrite PrintType to print "Car" 
}; 


// In main 
void main() 
{ 
Vehicle *s = new Car(); 
s->PrintType(); // Prints "Vehicle" 

// If PrintType was virtual then the type of s will be evaluated at runtime and the inherited function will be called printing "Car" 
}