我们知道需要虚拟析构函数。
Base *bptr = new Derived();
delete bptr;
如果派生类对象由基类指针指向,并且当对象超出范围时,除非析构函数是虚拟的,否则只调用Base类析构函数。
我想知道构造函数在这种情况下如何正常工作。 由于Base指针指向Derived对象,因此只应调用Base构造函数。它是如何正确调用派生类构造函数的。
请解释一下这背后的原因。
答案 0 :(得分:2)
new Derived()在任何地方都没有基类引用。您甚至可以选择将其分配给任何东西。因此,分配给结果指针的内容不会影响构造。
答案 1 :(得分:2)
执行以下操作时:
Base *bptr = new Derived();
您正在调用new
类的Derived
运算符,因为这就是您正在构建的内容。
当您将Derived*
返回的new
分配给Base*
时,您只是向上转换指针,这是一个隐式操作。
答案 2 :(得分:2)
使用new
创建对象时,我们拥有对象的完整信息;
new Derived(); // static type is same as dynamic type
指定指针的LHS部分无关紧要。这就是为什么你不需要构造函数的virtual
机制。有关详细信息,请参阅Bjarne Stroustrup页面。
其他注意,需要virtual
析构函数,因为您正在使用指向delete
对象的指针。
delete bptr; // static type may not be same as dynamic type
答案 3 :(得分:0)
您 明确说 您要构建Derived
的实例:
Base *bptr = new Derived();
表示如果键入class Derived
,请构造一个对象,然后请在bptr
中存储指向该对象的指针。因此,编译器 无需猜测或推断 。
将其与:
进行比较new Derived();
创建class Derived
的对象并泄漏该对象。编译器也无需猜测或演绎。这两个片段之间的唯一区别是前者存储指针而后者不存在。