【问题标题】:Destructor on polymorphic placed stuff多态放置的东西的析构函数
【发布时间】:2013-07-24 15:05:50
【问题描述】:

如果对象是使用placement new 创建的多态类型,有没有办法在对象上调用析构函数?

class AbstractBase{
public:
    ~virtual AbstractBase(){}
    virtual void doSomething()=0;
};

class Implementation:public virtual AbstractBase{
public:
    virtual void doSomething()override{
        std::cout<<"hello!"<<std::endl;
    }
};

int main(){
    char array[sizeof(Implementation)];
    Implementation * imp = new (&array[0]) Implementation();
    AbstractBase * base = imp; //downcast
    //then how can I call destructor of Implementation from
    //base? (I know I can't delete base, I just want to call its destructor)
    return 0;
}

我只想通过指向其虚拟基础的指针来破坏“实现”...这可能吗?

【问题讨论】:

  • base-&gt;~AbstractBase(),或imp-&gt;~Implementation()。你选。
  • 这甚至不是有效的 C++。你可以delete base,它会调用派生的虚拟析构函数。您确定要在此处使用虚拟继承吗?
  • 是的,你是对的! ideone.com/Dv4JpO 谢谢!美化凯西的解决方案就足够了:)。
  • 不能保证array 正确对齐以存储Implementation - 使用std::aligned_storage&lt;sizeof(Implementation)&gt;::type 而不是char[sizeof(Implementation)]
  • @Aesthete 调用delete base 将调用未定义的行为:“在第一种选择(删除对象)中,delete 的操作数的值可能是空指针value,指向由先前的 new-expression 创建的非数组对象的指针,或指向表示此类对象的基类的子对象(1.8)的指针(第 10 条)。如果不是,行为未定义。” [expr.delete]/2

标签: c++ c++11 placement-new virtual-destructor


【解决方案1】:

矫枉过正的答案:使用unique_ptr 和自定义删除器!

struct placement_delete {
  template <typename T>
  void operator () (T* ptr) const {
    ptr->~T();
  }
};

std::aligned_storage<sizeof(Implementation)>::type space;
std::unique_ptr<AbstractBase,placement_delete> base{new (&space) Implementation};

Live at Coliru.

【讨论】:

  • 我认为您应该将对齐作为第二个参数提供给aligned_storage。不过,这似乎不是必需的。
  • 示例:std::aligned_storage&lt;sizeof(Implementation), alignof(Implementation)&gt; :: type
  • 哈哈!你读懂了我的想法,我需要将它与 unique_Ptr 删除器 Casey 一起使用:p
  • @DyP 对齐存储的第二个参数 - 对齐 - 具有“对任何大小不大于 [第一个参数] 的任何 C++ 对象类型的最严格对齐要求”的神奇默认值(§ 20.9.7.6 表 57)。即,malloc::operator new 在分配该大小时将使用相同的对齐方式。
  • malloc 使用 16。这对于 AVX 类型来说是不够的。因此_aligned_malloc 存在其他对齐要求。s
猜你喜欢
  • 2012-12-22
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-21
  • 2018-01-17
相关资源
最近更新 更多