C++ 在异常类中使用unique_ptr安全吗
使用独特的ptr安全吗? 当我在析构函数中使用cout时,有时它会多次调用。-所以它会不断地复制。如果从一个对象复制两个副本,数据可能会丢失C++ 在异常类中使用unique_ptr安全吗,c++,exception,smart-pointers,unique-ptr,C++,Exception,Smart Pointers,Unique Ptr,使用独特的ptr安全吗? 当我在析构函数中使用cout时,有时它会多次调用。-所以它会不断地复制。如果从一个对象复制两个副本,数据可能会丢失 #include <memory> class MyException { std::unique_ptr<Type> data; MyException(); ~MyException() {cout<<"test"<<endl;} MyException(MyExce
#include <memory>
class MyException
{
std::unique_ptr<Type> data;
MyException();
~MyException() {cout<<"test"<<endl;}
MyException(MyException ex&);
};
int main()
{
try
{
try
{
throw MyException();
}
catch (const MyException& ex)
{
throw;
//or?
throw ex; //will be copied?
}
return 0;
}
catch(const MyException/*& will be missed. will ex be copied?*/ ex)
{
throw; //wich ex will be re-throw, copy or original?
//or?
throw ex; //will be copied?
}
}
正如你所发现的,你应该总是说
throw代码>当您想重新抛出异常时,而不是抛出ex代码>。实际上,抛出ex
将进行复制(如果ex
是对基类的引用,则进行切片!)
因此,始终通过引用捕获,并且始终在不命名异常的情况下重新抛出。对于gcc 4.7.3,您的示例无法编译,并抱怨MyException缺少副本构造函数。这是在它第一次抛出的行中,因此throw MyException()
本身已经想要创建一个副本(至少在gcc中是这样)。另请参见和
要回答您关于在异常中使用指针是否是良好做法的问题,我通常会说不。除非要装载到异常上的数据非常大(这可能是一个设计问题),否则应该首选堆栈分配的数据结构。无论如何,在异常处理过程中,性能不应该是主要的考虑因素,所以复制周围的内容并不是一个真正的问题
如果你真的需要一个指针(也许Type
没有复制构造函数,你不能改变它),使用shared\u ptr
可以在紧要关头帮助你,尽管我觉得这是一个难看的破解。我可能会尝试将通过异常传递的信息减少到最低限度,以帮助调用方识别和处理问题
编辑:我在第15.1节第5段中找到了相关章节:
当抛出的对象是类对象时,复制/移动构造函数和析构函数应该是可访问的,即使复制/移动操作被省略
<> P>不使用复制构造函数,抛出异常对象实际上不是合法的C++。这是肯定的。但是,可能还有其他一些点未指明是否制作了副本。vs 2012。输出中带有“throw;”-1“test”。输出中带有“throw ex;”-2“test”。2析构函数=2对象…=>创建了副本。例如,我使用共享\u ptr
在不同副本之间传递异常的调用堆栈。
std::exception_ptr ex = std::current_exception();
std::rethrow_exception(ex);