我开始使用C++11,特别是广泛地使用unique_ptr来使代码具有异常安全性和更易读的所有权。这通常效果很好,直到我想抛出一个unique_ptr。我有一个错误码(在许多地方抛出,在一个地方捕获),它创建了复杂的状态。由于动态分配的内存的所有权逻辑上从抛出者转移到了接收者,因此unique_ptr似乎是指示这一点并清楚地表明接收者已经获取堆对象的合适类型。但是在Visual Studio 2013中免费使用时没有起作用。以下是一个简化的代码示例,虽然不再类似于任何有用的东西,但引出了这种行为:
// cl /nologo /EHsc /W4 test1.cpp
#include <memory>
using std::unique_ptr;
class IError
{
public:
virtual ~IError() {};
virtual void DoStuff();
};
unique_ptr<IError> Error();
int Foo() { throw Error(); }
int main(void)
{
try {
Foo();
}
catch(unique_ptr<IError> Report)
{
Report->DoStuff();
}
return 0;
}
编译器会输出以下信息:
test1.cpp
test1.cpp(13) : warning C4673: throwing 'std::unique_ptr<IError,std::default_delete<_Ty>>' the following types will n
ot be considered at the catch site
with
[
_Ty=IError
]
test1.cpp(13) : warning C4670: '_Unique_ptr_base<class IError,struct std::default_delete<class IError>,1>' : this bas
e class is inaccessible
test1.cpp(13) : error C2280: 'std::unique_ptr<IError,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,
std::default_delete<_Ty>> &)' : attempting to reference a deleted function
with
[
_Ty=IError
]
C:\bin\Visual Studio Express 2013\VC\INCLUDE\memory(1486) : see declaration of 'std::unique_ptr<IError,std::d
efault_delete<_Ty>>::unique_ptr'
with
[
_Ty=IError
]
我哪里做错了?
Syl
所说,抛出时按值传递,捕获时按引用传递。 - Sebastian Hoffmann