如何删除通过放置new运算符构造的对象?

发布于 2024-11-24 09:15:55 字数 551 浏览 3 评论 0原文

char * buf = new char[sizeof(T)];
new (buf) T;
T * t = (T *)buf;
//code...
//here I should destruct *t but as it is argument of template and can be
//instantiated via basic types as well (say int) so such code 
/*t->~T();*/
//is incorrect (maybe correct? Strange, but it works on VS 2005 for basic types.)
//and this code 
/*delete t;*/ 
//crashes the program.
delete [] buf;

那么破坏t的正确方法是什么?

PS上面的代码仅用于描述我的问题,与我要编写的代码没有真正的关系。所以请不要给出类似的答案(为什么使用placement new 而不是non-placement?或类似的东西)

char * buf = new char[sizeof(T)];
new (buf) T;
T * t = (T *)buf;
//code...
//here I should destruct *t but as it is argument of template and can be
//instantiated via basic types as well (say int) so such code 
/*t->~T();*/
//is incorrect (maybe correct? Strange, but it works on VS 2005 for basic types.)
//and this code 
/*delete t;*/ 
//crashes the program.
delete [] buf;

So what is correct way to destruct t?

P.S. The code above is only for describing my problem, and have not real relationship with code I'm going to write. So please don't give answers like (Why use placement new instead of non-placement? or something similar)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吾家有女初长成 2024-12-01 09:15:55

...也通过基本类型实例化(比如int),所以这样的代码

t->~T(); 不正确
...

错误。即使 T 可以是原始类型,该代码在模板代码中也是合法且正确的。

C++ 标准:5.4.2

5.2.4 伪析构函数调用 [expr.pseudo]

  1. 使用
    . 或箭头 -> 运算符后面的伪析构函数名称表示
    由类型名称命名的非类类型的析构函数。结果
    只能用作函数调用operator()的操作数,
    并且此类调用的结果的类型为 void。唯一的效果就是
    计算点或箭头之前的后缀表达式。
  2. 点运算符的左侧应为标量类型。左边
    箭头运算符的手侧应为指向标量类型的指针。
    该标量类型是对象类型。指定的类型
    伪析构函数名称应与对象类型相同。
    此外,伪析构函数名称中的两个类型名称
    形式 ::opt Nested-name-specifieropt type-name :: ∼ type-name
    指定相同的标量类型。简历不合格的版本
    对象类型和伪析构函数名称指定的类型
    应为同一类型。

...instantiated via basic types as well (say int) so such code

t->~T(); is incorrect
...

Wrong. That code is legal and correct in template code even if T can be a primitive type.

C++ standard: 5.4.2

5.2.4 Pseudo destructor call [expr.pseudo]

  1. The use of a
    pseudo-destructor-name after a dot . or arrow -> operator represents
    the destructor for the non-class type named by type-name. The result
    shall only be used as the operand for the function call operator (),
    and the result of such a call has type void. The only effect is the
    evaluation of the postfix expression before the dot or arrow.
  2. The left hand side of the dot operator shall be of scalar type. The left
    hand side of the arrow operator shall be of pointer to scalar type.
    This scalar type is the object type. The type designated by the
    pseudo destructor- name shall be the same as the object type.
    Furthermore, the two type-names in a pseudodestructor- name of the
    form ::opt nested-name-specifieropt type-name :: ˜ type-name shall
    designate the same scalar type. The cv-unqualified versions of the
    object type and of the type designated by the pseudo-destructor-name
    shall be the same type.
好菇凉咱不稀罕他 2024-12-01 09:15:55

首先通过直接调用析构函数来析构对象:

t->~T();

然后通过对从 new[] 返回的指针调用 delete[] 来销毁内存:

delete []buf;

You first destruct the object by directly calling the destructor:

t->~T();

Then you destroy the memory by calling delete[] on the pointer returned from new[]:

delete []buf;
肥爪爪 2024-12-01 09:15:55

调用析构函数

T * t = (T *)buf;
t->~T();

,然后使用 delete[] buf 释放内存。显式调用析构函数正是使用放置 new 创建的对象的做法。

Call the destructor

T * t = (T *)buf;
t->~T();

then free memory with delete[] buf. Calling destructors explicitly is exactly how it is done for objects created with placement new.

山川志 2024-12-01 09:15:55

内存实际上是使用char*分配的; 您正在使用 delete[] buf正确释放它。在本例中,您只需为 t 调用析构函数 t->~T() 即可。无需删除 t;

Placement new 在这种情况下,仅用于构造对象,而不用于内存分配。

The memory was actually allocated using char*; which you are properly freeing using delete[] buf. You just need to call the destructor t->~T() in this case for t. No need to delete t;.

Placement new in this case, is used only to construct the object not for the memory allocation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文