仅调用驱动类的析构函数 查看C++语言标准,有没有方法调用派生类析构函数,而不调用基类的析构函数?< /P>

仅调用驱动类的析构函数 查看C++语言标准,有没有方法调用派生类析构函数,而不调用基类的析构函数?< /P>,c++,inheritance,casting,type-conversion,C++,Inheritance,Casting,Type Conversion,那么,上课呢 class Base { public: virtual ~Base() {} }; class Derived : public Base { public: ~Derived();}; 如果可能的话,我们可以编写如下代码 Base *basePtr = new Derived(); //do something with basePtr // Now somehow destroy Derived while keeping Base - call ~Derived() o

那么,上课呢

class Base { public: virtual ~Base() {} };
class Derived : public Base { public: ~Derived();};
如果可能的话,我们可以编写如下代码

Base *basePtr = new Derived();
//do something with basePtr

// Now somehow destroy Derived while keeping Base - call ~Derived() only, 
// line below however will call both ~Derived() and ~Base() - how it can be done?
dynamic_cast<Derived*>(basePtr)->~Derived(); 
加上在调用new Derived()和销毁派生类之间操纵basePtr对基对象所做的任何修改


或者,这是禁止的,并且不可能做到吗?

析构函数会按与构造相反的顺序自动调用。我不相信有任何方法可以解决这个问题。

除非派生类与基类无关,否则这是不可能的


析构函数是自动调用的。显式调用析构函数可能会导致未定义的行为。

否,这是不可能的。该标准要求销毁派生对象会销毁整个对象,包括基本子对象。根据C++对对象生命周期的理解,其他任何东西都不会是一种破坏

根据您想要实现的内容,考虑将基础复制到派生的第一个

std::unique_ptr<Base> basePtr(new Derived());
//do something with basePtr

basePtr.swap(std::unique_ptr<Base> (new Base(*basePtr))); //splice the Base part out of the derived object

//basePtr now points to the spliced Base object.
std::unique_ptr basePtr(新派生的());
//用basePtr做点什么
basePtr.swap(std::unique_ptr(新基(*basePtr))//将基础零件从衍生对象中拼接出来
//basePtr现在指向拼接的基础对象。

另一种方法是在一个
boost::optional
(或只是一个pimpl)中保留派生的其他成员,并将其重置,以获得一个仍然具有基类部分的“剥离”派生对象。但是,这不会影响虚拟功能分派。

由于您已经制定了问题,因此无法实现您的要求。除非存在内存泄漏,否则显式调用析构函数不会导致未定义行为的唯一情况是,如果对象是由新位置创建的。即使这样,调用析构函数也会自动调用每个成员和基类的析构函数

这是应该的。否则,编写正确的容器类或内存管理器将非常困难

该标准规定,对象一旦进入析构函数,其生命周期即告结束。它不会成为基类对象。它完全不再是一个对象。此外,如果不是这样,那么在这样一个技巧之后,从多个基派生的类的状态会是什么


最终,这种功能的“需求”是糟糕设计的标志。我猜您的用例更可能需要组合。看看你是否能用一个新类来解决这个问题,这个新类包含一个当前基类的实例和一个可选的、可替换的(指向的智能指针)虚拟类的组件,这个虚拟类是当前派生类的接口和新的公共基。这样,您就可以在不接触基座的情况下移除(并销毁)这些子对象。

@NPE如果这是可能的,如何做到????用例的动机是问题be,我单独问了这一部分,因为现在我很好奇它在理论上是否可能,以及如何做到这一点……事实上,我在保持
Base
位的同时没有注意到这一点。我收回我以前的评论。听起来像是XY问题……你可以显式调用析构函数,而无需重新放置,假设从未调用析构函数,也就是说。内存几乎肯定是泄漏的。@Griwes很好,我完全忘记了内存泄漏。我相应地修改了我的答案。
std::unique_ptr<Base> basePtr(new Derived());
//do something with basePtr

basePtr.swap(std::unique_ptr<Base> (new Base(*basePtr))); //splice the Base part out of the derived object

//basePtr now points to the spliced Base object.