可以抛出具有私有拷贝构造函数的对象吗?

时间:2012-04-11 09:54:06

标签: c++ visual-studio-2010 exception private copy-constructor

我遇到了一些我不清楚的例外问题。在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;
}

这合法吗?

2 个答案:

答案 0 :(得分:13)

这不合法。标准15.1 / 5

  

如果可以在不改变的情况下消除临时对象的使用   除了执行构造函数之外,程序的含义   和使用临时对象相关的析构函数   (12.2),然后可以直接初始化处理程序中的异常   使用throw表达式的参数。 当抛出的对象是一个   class对象,以及用于初始化的复制构造函数   临时副本无法访问,程序格式不正确(即使是   否则可以消除临时对象)。同样,如果   该程序是无法访问该对象的析构函数   形成不良(即使临时物体可能是其他情况)   消除)。

答案 1 :(得分:2)

不,不是。

  

15.1.5当抛出的对象是类对象时,应该可以访问复制/移动构造函数和析构函数,   即使删除了复制/移动操作