硬核题: 抛出一个构造函数和析构函数会输出的类

硬核题: 抛出一个构造函数和析构函数会输出的类#

大概率不考, 但理论很简单, 建议了解一下.

异常抛出的对象#

异常抛出时是要抛出一个对象的, 那么这个对象应该存放在哪?

显然不能存放在栈上, 因为 正常题: 抛出时栈回溯 (stack unwinding) 中已经指出, 在栈回溯的过程中, 这些栈上的自动存储对象都需要被析构. 所以当以 throw object; 抛出时, 会调用拷贝构造函数创建一个新的对象, 它不存放在栈中.

直到异常处理完成, 这个异常抛出的对象才会被析构.

 1void function() {
 2  try {
 3    Printer printer{Info{.ctor = "i", .copy_ctor = "n", .dtor = "t"}};
 4    throw printer;
 5  } catch (Printer& printer) {
 6    Printer another{Info{.ctor = "8", .dtor = "_"}};
 7  }
 8}
 9
10int main() {
11  function();
12}

异常捕获时#

假设抛出了类型 Printer,

  • 如果 catch 中写的是 catch (Printer printer), 则还需要发生拷贝.

  • 如果 catch 中写的是 catch (Printer& printer), 则直接引用异常抛出的对象.

 1void function() {
 2  try {
 3    Printer printer{Info{.ctor = "i", .copy_ctor = "n", .dtor = "t"}};
 4    throw printer;
 5  } catch (Printer printer) {
 6    Printer another{Info{.ctor = "8", .dtor = "_"}};
 7  }
 8}
 9
10int main() {
11  function();
12}