delete(Object)是否等效于调用Object .~Object()

时间:2012-05-24 13:10:27

标签: c++ memory

我有几个连接到AngelScript引擎的课程。这个引擎使用有趣的方式来分配对象:它分配所需的内存量(可能带有malloc()),当作者建议使用这样的结构在这个内存中创建对象时:

static void Constructor(ObjectType *thisPointer)
{
    new(thisPointer) ObjectType();
}

和这样的代码来销毁对象:

static void Destructor(ObjectType *thisPointer)
{
     thisPointer->~ObjectType();
}

我有几个问题:

  • 这种方式使用析构函数是否正确? (Eclipse将此判断为错误)据我所知,此代码应该在不释放内存的情况下调用析构函数(调用free()
  • 是否可以使用delete(thisPointer)(或类似的东西)而不是这种结构,它是否相同? (至少这段代码在编译和运行时没有出错)
  • 还有其他方法可以在不释放内存的情况下调用析构函数吗?

提前谢谢。

2 个答案:

答案 0 :(得分:12)

C ++在这里有点误导:

构造和内存管理实际上是完全不相关的过程,为方便起见,C ++在newdelete中一起使用。

但是,C ++实际上并没有专门的语法来调用现有内存上的构造函数 - 要做到这一点,你需要使用“placement new”语法实际上不是一个传统的new - 也就是说,它没有分配内存。

另一方面,一种语法来调用对象的析构函数。并且您的代码正确使用它。不,使用delete不等同,除了调用析构函数之外,它还会释放内存。

将此与std::allocator类进行比较,该类具有方法(及其相应的语义)

  • allocate(== ::operator new(sizeof T)
  • deallocate(== ::operator delete(&x)
  • construct(== new (&x) T()
  • destroy(== x.~T()

这些对应于对象生命周期的不同方面。

答案 1 :(得分:5)

  

以这种方式使用析构函数是否正确?

是。您使用placement-new就地构造了对象,因此必须使用显式析构函数调用来销毁它(假设它有一个非平凡的析构函数)。

  

是否可以使用delete(thisPointer)(或类似的东西)而不是这种结构,它是否相同?

没有。 delete将尝试使用operator delete()将内存释放到免费商店;这仅在分配了正常new表达式(或者可能明确使用operator new())时才有效。

  

还有其他方法可以在不释放内存的情况下调用析构函数吗?

不是真的。调用析构函数当然是调用析构函数的最清晰,最简单的方法。