首页 > 代码库 > 为什么构造函数不能为虚函数,而析构函数可以为虚函数
为什么构造函数不能为虚函数,而析构函数可以为虚函数
1. 构造函数为什么不能为虚函数?
a. 存储空间角度: 虚函数的调用需要虚函数表指针,而该指针存放在对象的内容空间中,需要调用构造函数才可以创建他的值,否则即使开辟了空间,则虚表指针为随机值,不会找到构造函数;若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间,更没有虚函数表地址用来调用虚函数——构造函数了。
b. 使用上: 从实现上看,vbtl在构造函数调用后才建立,因而构造函数不可能成为虚函数;
虚函数主要是实现多态,在运行时才可以明确调用对象,根据传入的对象类型,来调用函数当一个构造函数被调用时,它做的首要的事情之一是初始化它的V P T R。因此,它只能知道它是“当前”类的,而完全忽视这个对象后面是否还有继承者。当编译器为这个构造函数产生代码时,它是为这个类的构造函数产生代码- -既不是为基类,也不是为它的派生类(因为类不知道谁继承它)。
c. 所以它使用的V P T R必须是对于这个类的V TA B L E。而且,只要它是最后的构造函数调用,那么在这个对象的生命期内, V P T R将保持被初始化为指向这个V TA B L E, 但如果接着还有一个更晚派生的构造函数被调用,这个构造函数又将设置V P T R指向它的 V TA B L E,等.直到最后的构造函数结束。V P T R的状态是由被最后调用的构造函数确定的。这就是为什么构造函数调用是从基类到更加派生 类顺序的另一个理由。
2.析构函数可以使用虚函数?
对象已经创建,虚表指针存放析构函数的地址,基类与派生类都含有析构虚函数,创建基类与子类对象,都含有各类的虚表指针,当写通用函数时,运行根据传入对象的类型确定析构函数的地址,然后调用该析构函数。 但析构却不一定,我们往往通过基类的指针来销毁对象。这时候如果析构函数不是虚函数,就不能正确识别对象类型从而不能正确调用析构函数。
为什么构造函数不能为虚函数,而析构函数可以为虚函数