将源码中的函数调用解释为执行特定的函数代码块被称为函数名联编。
在C语言中。这很easy,由于每一个函数名都相应于一个不同的函数。
在C++中,由于函数重载的缘故。这项任务更复杂。编译器必须查看函数參数以及函数名才干确定使用哪个函数。然而,C/C++编译器可以在编译过程中完毕这样的联编。
在编译过程中进行联编称为静态联编。又称为早期联编。只是虚函数使这项工作变得更困难。
由于编译器不知道将选择哪种类型的对象。所以,编译器必须生成可以在程序执行时选择正确的虚方法的代码。这被称为动态联编,又称为晚期联编。
通常, C++不同意将一种类型的地址赋给还有一种类型的指针,也不同意一种类型的引用指向还有一种类型:
double x = 2.5;
int* pi = &x;//invalid assignment
long& r1 = x;//invalid assignment
只是,正如我们看到的。 指向基类的引用或指针能够引用派生类对象,而不必进行显示类型转换。
将派生类引用或指针转换为基类引用或指针被称为向上强制转换,这使公有继承不须要进行显示类型转换。该规则是is-a关系的一部分。向上强制转换时可传递的,也就是说,假设A派生出B,B派生出C,则A指针或引用能够引用A对象、B对象或C对象。
相反的过程---将基类指针或引用转换为派生类指针或引用---称为向下强制转换, 假设不使用显示类型转换。则向下强制转换时不同意的。
3、编译器对非虚方法使用静态联编,对虚方法使用动态联编。C++编译器默认使用静态联编。
4、虚函数的工作原理
通常,编译器处理虚函数的方法是:给每一个对象加入一个隐藏成员。隐藏成员中保存了一个指向函数地址数组的指针。
这样的数组称为虚函数表。
虚函数表中存储了为类对象进行生明的虚函数的地址。比如,基类对象包括一个指针。该指针指向基类中全部虚函数的地址表。派生类对象将包括一个指向独立地址表的指针。假设派生类提供了虚函数的新定义,该虚函数表将保存新函数的地址;假设派生类没有又一次定义虚函数,该虚函数表将保存函数原始版本号的地址。假设派生类定义了新的虚函数。则该函数的地址也将被加入到虚函数表中。
5、注意事项
假设在派生类中又一次定义函数。将不是使用同样的函数特征标覆盖基类声明。而是隐藏同名的基类方法,无论參数特征标怎样。这将引出两条经验规则:
①假设又一次定义继承的方法,应确保与原来的原型全然同样,但假设返回类型是基类引用或指针,则能够改动为指向派生类的引用或指针。这样的特性被称为返回类型协变,由于同意返回类型随类类型的变化而变化。
②假设基类声明被重载了,则应在派生类中又一次定义全部的基类版本号。
假设仅仅又一次定义一个版本号。则另外两个版本号将被隐藏。派生类对象将无法使用它们。