【问题标题】:Can't call explicitly destructor when object passed as reference对象作为引用传递时无法显式调用析构函数
【发布时间】:2017-06-02 18:15:39
【问题描述】:

我在 main 中有以下代码:

void *pmemory;
pmemory = malloc(ONEGIG_SIZE);
PoolAllocator* poolAllocator =  new PoolAllocator(sizeof(Obj), __alignof(Obj), ONEGIG_SIZE, pmemory);


Obj *obj1 = allocator::allocateNew(*poolAllocator, Obj("Temp"));
allocator::deallocateDelete(*poolAllocator, obj1);

而deallocateDelete()方法中的代码如下:

template<class T> void deallocateDelete(Allocator& allocator, T& object)
{
    object.~T();
    allocator.deallocate(&object);
}

我注意到,如果我将 T 对象作为参考传递给 deallocateDelete() 方法,则以下行 ( object.~T(); ) 不起作用,我的意思是不调用析构函数。但是,如果我将参数更改为指针 T* 对象,则调用析构函数。谁能解释一下为什么会这样?

【问题讨论】:

  • 你调用指针的析构函数(不是它指向的对象),然后在指针的内存上调用deallocate(同样不是对象)。
  • void deallocateDelete 中,T 的类型是Obj*。看起来您希望它是 Obj
  • 你应该永远有理由直接调用析构函数 - 除非在分配器内高度专业化的代码中和/或在处理放置新时。在大多数情况下,您通常应该永远处理所有这些问题。你为什么要这么做?
  • @Jesper Juhl 因为我使用的是placement-new,所以像这样 return new (allocator.allocate(sizeof(T), __alignof(T))) T(t); }
  • @JesperJuhl "除了可能在分配器内高度专业化的代码中"这似乎正是 OP 的情况。

标签: c++ memory-management dynamic-memory-allocation


【解决方案1】:

我的意思是没有调用析构函数

实际上,在技术上调用了析构函数。只是T的析构函数很琐碎,所以无法观察到它的调用。

我怀疑你认为TObj。但事实并非如此:您传递给函数的对象是 Obj*,因此推导出的参数是 Obj*&amp;

要使用Obj&amp; 参数调用deallocateDelete,您必须取消引用指针(就像取消引用指向分配器的指针一样):

allocator::deallocateDelete(*poolAllocator, *obj1);
//                                          ^

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多