2012-10-21 53 views
8

我想知道如何创建异常对象?以及为什么处理函数参数可以是非const引用?异常对象生存期

例如:

class E{ 
    public: 
    const char * error; 
    E(const char* arg):error(arg){ 
    cout << "Constructor of E(): ";} 

    E(const E& m){ 
     cout << "Copy constructor E(E& m): " ; 
     error=m.error; 
    } 
}; 



int main(){ 
try{ 
    throw E("Out of memory"); 

} 
catch(E& e){cout << e.error;} 

} 

输出: E()的构造:内存

所以我有throw E("out of memory")E("out of memory")只是暂时对象并没有对象有除E("out of memory")之外因为没有复制构造函数被调用而被创建。所以即使这E("out of memory")只是一个临时对象,我有一个处理程序采取非常量引用。

你能向我解释为什么这可能吗?

+1

'因为没有拷贝构造函数被调用。所以即使这个E(“内存不足”)只是一个临时对象,我也有一个处理程序需要一个非const引用, - http://en.wikipedia.org/wiki/Copy_elision –

+0

@skwllsp:so这是由于optimization.does这意味着临时对象没有被创建,它的参数直接传递给异常对象? – AlexDan

回答

10

想知道如何创建异常对象?

当你这样做:

throw E("Out of memory"); 

您在本地创建(类型E)的对象。抛出过程将这个对象拷贝到一些未被标准定义的私有内存位置。因此被抛出的对象必须是可复制的。

注意:允许编译器优化拷贝并直接在私有位置创建拷贝。所以它不被复制的事实是因为编译器优化了副本(所以它不再是本地的)。尝试使复制构造函数私有,现在它将无法编译。

以及为什么处理函数参数可以是非const引用?

当你捕捉对象:

catch(E& e) 

您是在它被复制到私人的位置获得的对象的引用。它不是一个const(或临时)值,所以你可以有一个正常的引用。

+0

该捕获参考多长时间? – xaxxon

+0

@xaxxon:http://stackoverflow.com/a/1654187/14065 –