gpt4 book ai didi

c++ - 当构造函数抛出异常时,RAII 是如何工作的?

转载 作者:IT老高 更新时间:2023-10-28 21:57:09 26 4
gpt4 key购买 nike

我正在学习 C++ 中的 RAII 习语,以及如何使用智能指针。

在我的阅读中,我遇到了两件在我看来似乎相互矛盾的事情。

引自 http://www.hackcraft.net/raii/ :

...if a member object with RAII semantics has been created and an exception happens before the constructor has completed then its destructor will be called as part of the stack unwinding. Hence an object which controls multiple resources can guarnatee their cleanup even if it isn’t fully constructed by using member RAII objects.

但引用自 http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.10 :

If a constructor throws an exception, the object's destructor is not run. If your object has already done something that needs to be undone (such as allocating some memory, opening a file, or locking a semaphore), this "stuff that needs to be undone" must be remembered by a data member inside the object.

然后第二个链接源建议使用智能指针来处理已经在构造函数中分配的东西的问题。

那么在这些场景中实际发生了什么?

最佳答案

您误解了第一句话。这并不难,因为它令人困惑。

if a member object with RAII semantics has been created and an exception happens before the constructor has completed then its destructor will be called as part of the stack unwinding.

这就是它所说的。这就是它的意思:

if a member object with RAII semantics has been created and an exception happens in the outer object before the outer object's constructor has completed then the member object's destructor will be called as part of the stack unwinding.

看到区别了吗?这个想法是成员对象完成了它的构造函数,但拥有类型没有。它在其构造函数中的某个位置(或在该构造函数之后初始化的另一个成员的构造函数)。这将导致其所有成员的析构函数被调用(即所有完成构造的成员),但不是它自己的析构函数。

这是一个例子:

class SomeType
{
InnerType val;
public:
SomeType() : val(...)
{
throw Exception;
}
};

当你创建一个 SomeType 实例时,它会调用 InnerType::InnerType。只要不抛出,它就会进入 SomeType 的构造函数。当它抛出时,它将导致 val 被销毁,从而调用 InnerType::~InnerType

关于c++ - 当构造函数抛出异常时,RAII 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9122331/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com