乐闻世界logo
搜索文章和话题

当构造函数抛出异常时,运行哪些析构函数?

5 个月前提问
4 个月前修改
浏览次数35

1个答案

1

当构造函数在执行过程中抛出异常,C++ 会负责清理在异常发生前已经成功构造的对象。具体来说,只有那些已经完成构造的成员变量和基类的析构函数会被调用。这是为了防止资源泄漏。

举一个例子来说明这一点:

cpp
#include <iostream> #include <stdexcept> class A { public: A() { std::cout << "A 构造" << std::endl; } ~A() { std::cout << "A 析构" << std::endl; } }; class B { public: B() { std::cout << "B 构造" << std::endl; } ~B() { std::cout << "B 析构" << std::endl; } }; class C { public: C() { std::cout << "C 构造" << std::endl; throw std::runtime_error("在 C 中抛出异常"); } ~C() { std::cout << "C 析构" << std::endl; } }; class Test { A a; B b; C c; public: Test() { std::cout << "Test 构造" << std::endl; } ~Test() { std::cout << "Test 析构" << std::endl; } }; int main() { try { Test t; } catch (const std::exception &e) { std::cout << "捕获异常: " << e.what() << std::endl; } return 0; }

在这个例子中,Test 类包含三个成员:A aB b,和C c。当尝试构造 Test 类的对象时:

  1. 首先构造成员 A a,成功后输出 "A 构造"。
  2. 接着构造成员 B b,成功后输出 "B 构造"。
  3. 然后尝试构造成员 C c,在构造过程中抛出异常,并输出 "C 构造" 和 "在 C 中抛出异常"。

因为 C c 的构造过程中发生了异常,它的析构函数不会被调用,因为它从未成功完成构造。但是,对于已经成功构造的 A aB b,它们的析构函数会被依次调用,输出 "B 析构" 和 "A 析构"。

这个机制确保了在构造过程中已经分配的资源能够被正确回收,防止资源泄漏。

2024年6月29日 12:07 回复

你的答案