2011-05-03 115 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" 
}