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
的正确方法是什么?
P.S。上面的代码仅用于描述我的问题,并且与我将编写的代码没有真正的关系。所以请不要给出答案(为什么使用展示位置new
而不是非展示位置?或类似的东西)
答案 0 :(得分:25)
... 也通过基本类型实例化(比如
int
)所以这样的代码
t->~T();
不正确 ...
错误。即使T
可以是基本类型,该代码在模板代码中也是合法且正确的。
C ++标准:5.4.2
5.2.4 伪析构函数调用[expr.pseudo]
- 使用a 点
.
或箭头->
运算符表示后的伪析构函数名称 type-name命名的非类类型的析构函数。结果 只能用作函数调用operator ()
的操作数, 并且这种调用的结果类型为void。唯一的影响是 在点或箭头之前评估后缀表达式。- 点运算符的左侧应为标量类型。左边 箭头操作符的手侧应为指向标量类型的指针。 此标量类型是对象类型。指定的类型 伪析构函数名称应与对象类型相同。 此外,伪结构中的两个类型名称 表格
醇>::opt nested-name-specifieropt type-name :: ˜ type-name
指定相同的标量类型。 cv不合格的版本 对象类型和伪析构函数名称指定的类型 应该是相同的类型。
答案 1 :(得分:11)
首先通过直接调用析构函数来破坏对象:
t->~T();
然后通过调用delete[]
返回的指针上的new[]
来销毁内存:
delete []buf;
答案 2 :(得分:7)
调用析构函数
T * t = (T *)buf;
t->~T();
然后使用delete[] buf
释放内存。显式调用析构函数正是如何使用展示位置new
创建的对象。
答案 3 :(得分:3)
实际使用char*
分配内存; 您正在使用 delete[] buf
正确释放。在这种情况下,您只需要为t->~T()
调用析构函数t
。无需delete t;
。
放置 new
仅用于构造不用于内存分配的对象。