C++ 运行时多态性中的构造函数行为
我们知道需要一个虚拟析构函数C++ 运行时多态性中的构造函数行为,c++,C++,我们知道需要一个虚拟析构函数 Base *bptr = new Derived(); delete bptr; 如果派生类对象由基类指针指向,并且当对象超出范围时,只有基类析构函数被调用,除非析构函数是虚拟的 我想知道在这种情况下构造函数是如何正常工作的。 因为基指针指向派生对象,所以应该只调用基构造函数。如何正确调用派生类构造函数 请向我解释这背后的原因。new-Derived()在任何地方都没有基类引用。您甚至可以选择不指定它。因此,结果指针的赋值不会影响构造。new-Derived()在
Base *bptr = new Derived();
delete bptr;
如果派生类对象由基类指针指向,并且当对象超出范围时,只有基类析构函数被调用,除非析构函数是虚拟的 我想知道在这种情况下构造函数是如何正常工作的。 因为基指针指向派生对象,所以应该只调用基构造函数。如何正确调用派生类构造函数
请向我解释这背后的原因。new-Derived()在任何地方都没有基类引用。您甚至可以选择不指定它。因此,结果指针的赋值不会影响构造。new-Derived()在任何地方都没有基类引用。您甚至可以选择不指定它。因此,结果指针的赋值不会影响构造。执行以下操作时:
Base *bptr = new Derived();
您正在为派生的
类调用新的
操作符,因为这就是您要构造的
当您将
new
返回的Derived*
分配给Base*
时,您只需向上投射作为隐式操作的指针。当您执行以下操作时:
Base *bptr = new Derived();
您正在为派生的
类调用新的
操作符,因为这就是您要构造的
当您将
new
返回的Derived*
分配给Base*
时,您只需向上投射指针,这是一个隐式操作。使用new
创建对象时,我们拥有对象的完整信息
new Derived(); // static type is same as dynamic type
指定指针的LHS部分是不相关的。这就是为什么构造函数不需要这种虚拟机制的原因。有关详细信息,请参阅的页面
另外,需要使用virtual
析构函数,因为您使用的是指向delete
对象的指针
delete bptr; // static type may not be same as dynamic type
使用new
创建对象时,我们拥有对象的完整信息
new Derived(); // static type is same as dynamic type
指定指针的LHS部分是不相关的。这就是为什么构造函数不需要这种虚拟机制的原因。有关详细信息,请参阅的页面
另外,需要使用virtual
析构函数,因为您使用的是指向delete
对象的指针
delete bptr; // static type may not be same as dynamic type
您明确地说您想要构造一个派生的实例:
Base *bptr = new Derived();
表示如果类型为派生类
,请构造一个对象,然后请在bptr
中存储指向该对象的指针。因此编译器没有任何东西可以猜测或推断
将其与:
new Derived();
它创建一个类派生的对象并泄漏该对象。编译器在这里也没有什么可以猜测或推断的。这两个代码段之间的唯一区别是前者存储指针,而后者不存储。您明确地说,您想要构造一个派生的
实例:
Base *bptr = new Derived();
表示如果类型为派生类
,请构造一个对象,然后请在bptr
中存储指向该对象的指针。因此编译器没有任何东西可以猜测或推断
将其与:
new Derived();
它创建一个类派生的对象并泄漏该对象。编译器在这里也没有什么可以猜测或推断的。这两个代码段之间的唯一区别是前者存储指针,而后者不存储。“如果派生类对象由基类指针指向,并且当对象超出范围时,只有基类析构函数被调用,除非析构函数是虚拟的。”-如果派生类的对象超出范围,调用派生类析构函数,而指向该对象的任何其他普通指针的存在和类型都是无关的。如果指向任何对象的普通指针超出范围,则不会调用任何对象。智能指针可以调用析构函数,在这种情况下,确实需要虚拟分派来确保它是派生类的析构函数new X
没有作用域。感谢您的更正。实际上我的意思是,当执行“delete bptr”时,只有基类析构函数被调用,除非析构函数是虚拟的。如果派生类对象由基类指针指向,并且当对象超出范围时,只有基类析构函数被调用,除非析构函数是虚拟的。-如果派生类的对象超出范围,则调用派生类析构函数,并且指向该对象的任何其他普通指针的存在和类型都是无关的。如果指向任何对象的普通指针超出范围,则不会调用任何对象。智能指针可以调用析构函数,在这种情况下,确实需要虚拟分派来确保它是派生类的析构函数new X
没有作用域。感谢您的更正。实际上我的意思是,当执行“delete bptr”时,只有基类析构函数被调用,除非析构函数是虚拟的。