当函数名被调用时,编译器将选择应该执行的代码,此时即称编译器绑定了函数名。换句话说,当函数被调用时,编译器就会将该该函数的名称和它的定义绑定在一起。
静态绑定发生在编译时,并将名称绑定到一个固定的函数定义,然后在每次调用该名称时执行该定义。例如,编译器使用静态绑定将以下语句中的 getName 绑定到 Person 类(而不是其他类)中的 getName 定义:
for (int k = 0; k <people.size (); k++)
{
cout << people [k] ->getName () << endl;
}
在静态绑定中,编译器使用编译时可用的类型信息。如果代码在继承层次结构中的不同类的对象上运行,则编译器可用的唯一类型信息将是用于访问所有对象的基类指针类型。因此,静态绑定将始终使用基类版本的成员函数。
相反,动态绑定发生在运行时。动态绑定仅在编译器可以确定运行时子类对象所属的确切类时才起作用。编译器然后使用这个运行时类型信息来调用该类中定义的函数版本。
为了使动态绑定成为可能,编译器将运行时类型信息存储在具有虚函数的类的每个对象中。动态绑定始终使用对象的实际类中的成员函数版本,而无视用于访问对象的指针的类。