c++ - 为什么类的字段是自动对象?

标签 c++ stack exe raii stack-unwinding

在我研究异常机制的过程中,我发现在堆栈展开时会调用对象字段的析构函数。让我明确解释一下:

class X
{
  File_ptr aa;
  Lock_ptr bb;
public:
 X(const char* x,const char* y):aa(x),bb(y){}
//.......
}

所以,现在如果 Lock_ptr 的构造函数抛出异常,对象 aa 将被销毁; 问题是“为什么”?我一直认为对象的字段不是通常的自动(本地)对象。它们是在构造函数初始化它们之前创建的。因此它们在超出构造函数范围后不能被销毁(否则它们会尽快被销毁构造函数完成了它的工作)

最佳答案

子对象(包括非静态数据成员)与其所属的完整对象具有相同的存储期限。这与说它们是自动的不同。自动对象在 block 的末尾被销毁。每当子对象的完整对象被销毁时,子对象也会被销毁。例如,如果使用 new 创建完整对象并使用 delete 销毁(即具有动态存储持续时间),则子对象也会在调用 时创建new,并在调用 delete 时销毁。另一方面,自动对象的子对象也是自动的。

如果X::bb 的构造函数抛出异常,则意味着无法构造X 类型的完整对象。所有已经构建的子对象,例如 X::aa,都必须被销毁,因为子对象与其完整对象具有相同的存储持续时间,没有完整对象就无法生存。

另一方面,如果整个 X 对象的构建成功完成,X::aa 和其他子对象将不会被销毁,直到(不久之后)完整的 X 对象被销毁。

C++ 的构造和销毁规则旨在保证,只要程序正常终止,每个创建的对象也恰好销毁一次。这对于 RAII 习语是必不可少的。在此示例中,如果 X::aa 在构造时获取资源,则语言必须确保释放这些资源。如果 X::aa 的析构函数在构造 X 失败时没有被调用,那么它应该在什么时候被调用?

关于c++ - 为什么类的字段是自动对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24457794/

相关文章:

c++ - 缓存不经意矩阵转置在 C++ 中的实现

c++ - 在 C 和 C++ 中 main() 应该返回什么?

c++ - 如何从堆栈中弹出所有值并将它们作为所有值的总和推回?

java - 堆栈集合、Push 与 addElement

c++ - HEAP_NO_SERIALIZE 堆中的多线程访问

c++ - 发生哪些线程异步操作

c++ - 通过创建局部变量减少堆栈指针

file - VB6 不会创建 EXE 文件 - 但它会使用吗?

php - 如何将 php (5.5 >7.0) 项目转换为 exe 文件?

python - 编译Python程序,但也输出颜色吗?