虚函数的定义要遵循以下重要规则:
1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行晚绑定的。
2.只有类的成员函数才能说明为虚函数,因为虚函数仅适合用与有继承关系的类对象,所以普通函数不能说明为虚函数。
3.静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。
4.内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义定义,但是在编译的时候系统仍然将它看做是非内联的。
5.构造函数不能是虚函数,因为构造的时候,对象还是一片未定型的空间,只有构造完成后,对象才是具体类的实例。
6.析构函数可以是虚函数,而且通常声明为虚函数。
在一个有虚函数的类中,编译器会设立一个虚函数表(虚表)用来记录对应的虚函数地址。每个地址对应一个虚指针,指针的大小为4个字节(编译器一般以4的倍数对其地址)。虚表为顺序存储。在类的实例对象中,会有一个虚表指针,用来指向虚表。
虚继承 是为了解决多重继承而设计的,避免重复拷贝。如下:
图(a),(b),(c)表示B继承自A,C继承自A,D继承自B和C,那么因为B和C都继承自A,因此会出现d的情况,在类D中会出现两个A,出现了重复拷贝,为了节省空间,可将B,C对A的继承定义为虚继承,A则成为虚基类,则继承图便成为图(e)。
代码如下:
【代码】
1 2 3 4 | class A; class B: public virtual A; //定义成虚继承 class C: public virtual A; //定义成虚继承 class D: public B, public C; //只会出现一个A |