【发布时间】:2018-10-06 17:31:14
【问题描述】:
当退出作用域时,是否有一种模式可以自动调用堆栈上的 placement-new 初始化对象的析构函数?我想跳过记住显式调用析构函数的需要。或者,是否有与 placement-new 不同的方法来构造具有可变大小 data[] 尾部的基于堆栈的对象?我用 g++。
/* g++ f.cpp -o f.exe */
/* 8< --- f.cpp ---- */
#include <stdio.h>
#include <stdlib.h>
#include <string>
class aclass {
public:
aclass(int size) : size_(size) {};
~aclass() { /* do something */ };
int size_;
char data[0];
};
void f(int size)
{
char v[sizeof(aclass) + size];
aclass *p = new(static_cast<void*>(&v)) aclass(size);
p->~aclass();
}
int main(int argc, char **argv)
{
f(10);
f(100);
return 0;
}
【问题讨论】:
-
我认为第一个问题是
v不一定与aclass正确对齐。 -
其实第一个问题是
char v[sizeof(aclass) + size];不是标准C++,因为size不是常量。 -
我不是 100% 确定,但如果您尝试以这种方式改变
data的大小仍然是未定义的行为,我不会感到惊讶,因为您有将其定义为静态大小 0(因此访问此数组的任何元素都将超出范围) -
data[0] 是 gcc 和 C 的常见习语。
-
绝对可以使用“基于范围的资源管理”(有时称为“资源获取即初始化”)来安排析构函数的自动调用。这样做将涵盖范围内的所有退出,包括正常和异常。
标签: c++ gcc g++ destructor placement-new