在下面的例子中
class X
{
int *r;
public:
X() {
cout << "X is created";
r = new int[10];
};
~X() {
cout<< "X is destroyed";
delete [] r;
};
};
class Y
{
public:
Y() {
X x;
throw 44;
};
~Y() {
cout << "Y is destroyed";
};
};
我从一个网站得到了这个 RAII 的例子,我有一些疑问。请帮忙。
- 在 x 的构造函数中,我们没有考虑“如果内存分配失败”的场景。
- 这里 Y 的析构函数是安全的,因为在 y 中,构造函数没有分配任何内存。如果我们还需要在 y 构造函数中进行一些内存分配怎么办?
最佳答案
在 X
的构造函数中, 如果 new
失败它会抛出一个异常(std::bad_alloc
)。这意味着构造函数永远不会完成,因此对象的生命周期永远不会开始,因此它的析构函数永远不会被调用(没有对象)并且 new[]
之间没有不匹配。和 delete[]
. (X
应该有一个用户声明的复制构造函数和一个用户声明的复制赋值运算符,因为如果构造成功并且对象被复制或赋值,提供的实现将破坏此保证。)
在Y
,如果它在它的构造函数中分配内存并且此分配成功,那么它需要确保在构造的其余部分在任何时候抛出异常时释放此内存,并且如果构造函数完成,则在析构函数中释放内存(假设内存设计为持续对象的生命周期长度)。
为了使这更容易,任何分配的内存都应该立即交给一个对象,该对象的唯一职责是释放内存。让一个类管理指向多个已分配内存块的原始指针是复杂且容易出错的管理代码的秘诀。
关于c++ - 资源获取是初始化 "RAII",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2484012/