我有关于throw-expressions和copy构造函数的问题。
#include <iostream>
class Foo
{
public:
Foo() { std::cout << "Foo::Foo() \n"; }
Foo(const Foo&) { std::cout << "Foo::Foo(const Foo&) \n"; }
~Foo() { std::cout << "Foo::~Foo() \n"; }
};
int main()
{
try
{
throw Foo();
}
catch (...)
{
std::cerr << "Error \n";
}
}
在C ++ 98 / C ++ 03中,此代码是否打印:
Foo::Foo()
Error
Foo::Foo(const Foo&)
Foo::~Foo()
和C ++ 11中的以下一项:
Foo::Foo()
Error
Foo::Foo(const Foo&)
Foo::~Foo()
或
Foo::Foo()
Error
Foo::~Foo()
我只在C ++ 11中看到过这个:
12.8复制和移动类对象[class.copy]
31 ... - 在throw-expression中,当操作数是a的名称时 非易失性自动对象(函数或catch子句除外) 参数)其范围不超出最内层的末端 封闭try-block(如果有的话),复制/移动操作 异常对象(15.1)的操作数可以省略 将自动对象直接构造到异常对象
答案 0 :(得分:2)
未定义异常对象的复制(或在C ++ 11中移动),但它必须是可复制的(或在C ++ 11中可移动),并且实现可以复制(或移动)它多次他们喜欢吝啬。
答案 1 :(得分:2)
我希望看到:
Foo::Foo() // construction
Foo::Foo(const Foo&) // copy to special throw location
Error // catch and print error
Foo::~Foo() // at the end of the catch block the exception object is destroyed.
or
Foo::Foo() // As above but compiler has optimized the copy out.
Error
Foo::~Foo()
这是因为:
throw Foo(); // Creates a local temporary object.
// The throw then copies (moves) the local temporary to an implementation
// specific location to preserve it while the stack is unwound.
但请注意:允许编译器忽略对象的副本(即使它们有副作用)。因此,在这种情况下,编译器可以优化代码,以在特定于实现的位置显式构造它。
另外值得注意的是:
catch (Foo e) // Copies the exception object from the implementation specific location
// to e so it can be used in the try block. Note this may also result in
// object slicing if you don;t catch the exact type.
catch (Foo const& e) // No copy required as you are using a reference
// Thus no chance of slicing.