gpt4 book ai didi

c++ - 在 C++ 析构函数中发生异常时,是否所有属性都自动销毁

转载 作者:太空狗 更新时间:2023-10-29 19:58:55 26 4
gpt4 key购买 nike

多年来我一直在使用 C++,但在使用可能被认为过时的东西的环境中。具体来说,我们没有使用 auto_ptr,也不允许在构造函数中分配内存。

继续前进,我以为我已经掌握了窍门,直到...请参阅以下代码:

    #include <memory>
#include <iostream>

using namespace std;

class Foo
{
public:
int x;
~Foo() { cout << "~Foo" << endl; }
};

class Bar
{
public:
Bar() { throw 0; }
~Bar() { cout << "~Bar" << endl; }
int y;
};

class HumBug
{
public:
HumBug();
virtual ~HumBug();

auto_ptr<Foo> foo;
auto_ptr<Bar> bar;
};

HumBug::HumBug()
{
cout << "before foo" << endl;
foo = auto_ptr<Foo>(new Foo);
cout << "after foo" << endl;
bar = auto_ptr<Bar>(new Bar);
cout << "after bar" << endl;
}

HumBug::~HumBug()
{
cout << "~HumBug" << endl;
}

int main()
{
try
{
HumBug humbug;
}
catch (...)
{
}
return 0;
}

我知道 HumBug 的析构函数不会被调用,因为异常发生在调用 HumBug 构造函数的过程中。我原以为创建的 Foo 属性会泄漏。然而 valgrind 说没问题:

==4985== Memcheck, a memory error detector
==4985== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==4985== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==4985== Command: ./a.out
==4985==
before foo
after foo
~Foo
==4985==
==4985== HEAP SUMMARY:
==4985== in use at exit: 0 bytes in 0 blocks
==4985== total heap usage: 3 allocs, 3 frees, 108 bytes allocated
==4985==
==4985== All heap blocks were freed -- no leaks are possible
==4985==
==4985== For counts of detected and suppressed errors, rerun with: -v
==4985== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

那么是不是虽然没有调用析构函数,属性仍然可靠地被销毁了?我在想,为了可靠地清理它,我必须将 HumBug 的构造函数重写为:

    HumBug::HumBug()
{
auto_ptr<Foo> new_foo (new Foo);
auto_ptr<Bar> new_bar (new Bar);
// no exceptions after this point
foo = new_foo;
bar = new_bar;
}

但事实并非如此。

我可以依靠这个吗?

最佳答案

[except.ctor]/2:

An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.

(强调我的)

子对象的构造函数将在内存初始化器列表中调用(你的是空的,因此会发生默认构造)。当进入ctor体时,所有的成员都已经构造成功,因此会调用它们的dtors。

关于c++ - 在 C++ 析构函数中发生异常时,是否所有属性都自动销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16613688/

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