Collected from here . . .
非虚拟成员函数是静态解析的。也就是说,成员函数是根据指向对象的指针(或引用)的类型(在编译时)静态选择的。
相比之下,虚拟成员函数是动态解析的(在运行时)。也就是说,成员函数是根据对象的类型(在运行时)动态选择的,而不是基于该对象的指针/引用的类型。这称为“动态绑定”。大多数编译器使用以下技术的一些变体:如果对象具有一个或多个虚拟函数,编译器会在对象中放置一个隐藏指针,称为“虚拟指针”或“v指针”。这个 v-pointer 指向一个名为“virtual-table”或“v-table”的全局表。
纯虚函数是必须在派生类中重写且无需定义的函数。使用奇怪的 =0 语法将虚函数声明为“纯”。例如:
class Base {
public:
void f1(); // not virtual
virtual void f2(); // virtual, not pure
virtual void f3() = 0; // pure virtual
};
Base b; // error: pure virtual f3 not overridden
这里,Base 是一个抽象类(因为它有一个纯虚函数),所以不能直接创建 Base 类的对象:Base(明确地)意味着是一个基类。例如:
class Derived : public Base {
// no f1: fine
// no f2: fine, we inherit Base::f2
void f3();
};
Derived d; // ok: Derived::f3 overrides Base::f3
虚拟或非虚拟围栏示例
#include <iostream>
using namespace std;
class Base {
public:
virtual void NameOf(); // Virtual function.
void InvokingClass(); // Nonvirtual function.
};
// Implement the two functions.
void Base::NameOf() {
cout << "Base::NameOf\n";
}
void Base::InvokingClass() {
cout << "Invoked by Base\n";
}
class Derived : public Base {
public:
void NameOf(); // *Virtual function*.
void InvokingClass(); // *Nonvirtual function.*
};
// Implement the two functions.
void Derived::NameOf() {
cout << "Derived::NameOf\n";
}
void Derived::InvokingClass() {
cout << "Invoked by Derived\n";
}
主要
int main() {
// Declare an object of type Derived.
Derived aDerived;
// Declare two pointers, one of type Derived * and the other
// of type Base *, and initialize them to point to aDerived.
Derived *pDerived = &aDerived;
Base *pBase = &aDerived;
// Call the functions.
pBase->NameOf(); // Call virtual function.
pBase->InvokingClass(); // Call nonvirtual function.
pDerived->NameOf(); // Call virtual function.
pDerived->InvokingClass(); // Call nonvirtual function.
}