我遇到了一些我不清楚的例外问题。在C ++中,当抛出一个对象时,它首先被复制到一个临时对象,然后临时对象被传递给捕获代码。该副本涉及使用对象的类复制构造函数。 AFAIK,这意味着如果一个类有一个私有拷贝构造函数,它就不能用作异常。但是,在VS2010中,以下代码编译并运行:
class Except
{
Except(const Except& other) { i = 2; }
public:
int i;
Except() : i(1) {}
};
int main()
{
try
{
Except ex1;
throw ex1; // private copy constructor is invoked
}
catch (Except& ex2)
{
assert(ex2.i == 2); // assert doesn't yell - ex2.i is indeed 2
}
return 0;
}
这合法吗?
答案 0 :(得分:13)
这不合法。标准15.1 / 5
如果可以在不改变的情况下消除临时对象的使用 除了执行构造函数之外,程序的含义 和使用临时对象相关的析构函数 (12.2),然后可以直接初始化处理程序中的异常 使用throw表达式的参数。 当抛出的对象是一个 class对象,以及用于初始化的复制构造函数 临时副本无法访问,程序格式不正确(即使是 否则可以消除临时对象)。同样,如果 该程序是无法访问该对象的析构函数 形成不良(即使临时物体可能是其他情况) 消除)。
答案 1 :(得分:2)
不,不是。
15.1.5当抛出的对象是类对象时,应该可以访问复制/移动构造函数和析构函数, 即使删除了复制/移动操作