gpt4 book ai didi

c++ - 如果抛出的异常总是异常对象的拷贝,为什么不调用这个复制构造函数?

转载 作者:可可西里 更新时间:2023-11-01 16:36:33 24 4
gpt4 key购买 nike

斯科特迈耶斯说:

C++ specifies that an object thrown as an exception is always copied and the copying is performed by the object's copy constructor.

但是在我的代码中:

struct test
{
test() { cout << "constructor is called" << endl; }
test(const test&) { cout << "copy constructor is called" << endl; }
~test() { cout << "destructor is called" << endl; }
};

void fun()
{
throw test();
}

int main()
{
try {
fun();
}
catch (test& t1) { cout << "exception handler" << endl; }
}

我没有看到异常对象的复制构造函数被调用。

如果我将 catch 更改为按值接收异常对象,那么它就是这样,但根据 Meyers 的引述,即使通过引用接收异常对象也应该被复制。

为什么不调用复制构造函数(即使通过引用执行异常处理)?

最佳答案

从语义上讲,Meyers 是正确的:

[C++11: 12.2/1]: Temporaries of class type are created in various contexts: binding a reference to a prvalue (8.5.3), returning a prvalue (6.6.3), a conversion that creates a prvalue (4.1, 5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering a handler (15.3), and in some initializations (8.5). [..]

[C++11: 15.1/4]: The memory for the temporary copy of the exception being thrown is allocated in an unspecified way, except as noted in 3.7.3.1. The temporary persists as long as there is a handler being executed for that exception.

但是,聪明的编译器可以省略拷贝,并且允许他们这样做而不考虑副作用。

[C++11: 12.8/31]: When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization. This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

  • [..]
  • when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move.
  • [..]

关于c++ - 如果抛出的异常总是异常对象的拷贝,为什么不调用这个复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8760813/

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