我可以通过以下方式避免复制对象吗?
MyClass Obj;
try {
throw &Obj;
}
catch(MyClass *a) {
}
答案 0 :(得分:10)
如果对象太昂贵而无法复制,则不应将其作为异常抛出 - 完全停止。异常类应该相当简单和轻量级。并且你应该总是通过引用捕获异常(可能通过const引用) - 捕获指针是糟糕的风格。所以你的代码应该写得更好:
try {
throw MyClass();
}
catch( const MyClass & a) {
}
在回复您的评论时,请:
struct A {
A() {}
private:
A( const A & ) {}
};
int main() {
throw A();
}
应该是一个错误。但是你根本不应该禁止复制你想要抛出的类作为例外 - 你为什么要这样做?
答案 1 :(得分:2)
不要这样做。
考虑这个程序:
#include <iostream>
#define X() (std::cout << __FUNCTION__ << "\n")
struct MyClass {
MyClass() { X(); }
~MyClass() { X(); }
};
void f() {
MyClass Obj;
throw &Obj;
}
int main() {
try {
f();
} catch(MyClass *a) {
X();
}
}
其输出为:
MyClass
~MyClass
main
请注意,在程序进入catch块之前,销毁了指向对象。这意味着我们不能在catch块中取消引用a
,严重限制其有用性。
答案 2 :(得分:0)
避免复制异常对象的唯一方法是将指针抛出到对象中,就像在示例中所做的那样。您必须确保对象是静态的或堆分配的,而不是在抛出期间离开代码块后将消失的本地对象。
修改:我想到了另一种方法。您可以使用指针作为成员创建自己的异常类(应该从std::exception
或其子节点派生),然后抛出它。如果您使用智能指针(如shared_ptr
),则无需担心所包含对象的生命周期。
答案 3 :(得分:0)
语法正确并且避免了复制,因为传递了引用。但是,通常会构造一个标准的无名异常对象,并由catch
语句捕获。