用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"
Run Code Online (Sandbox Code Playgroud)
没有(相同的代码,但遗漏了virtual):
// in main()
Derived* d = new Derived();
d->Foo(); // prints "Foo in Derived"
Base* b = new Derived();
b->Foo(); // prints "Foo in Base"
Run Code Online (Sandbox Code Playgroud)
所以区别在于没有virtual,没有真正的运行时多态性:调用哪个函数是由编译器决定的,具体取决于调用它的指针/引用的当前类型.
使用时virtual,对象维护一个虚函数列表(vtable),在其中查找要调用的函数的实际地址 - 在运行时,每次调用它的虚拟成员时.在此示例中,构造函数Foo隐式修改了条目Derived以指向被覆盖的函数,因此Foo通过Base-pointer 调用它并不重要.