2013-05-17 64 views
2

我读的C++的一些注意事项和遇到下列问题就来了构造函数和异常

问:一个构造函数可以抛出异常?构造函数失败时如何处理错误?

答:构造函数永远不会引发错误。

现在这个答案有点困惑我,只是为了确保我去了online并且读到你总是可以从构造函数中抛出异常。我只是想确定这样做是否会在笔记中出现错字,并且我可能不会错过重要的东西。

+2

鉴于'new'可以抛出,我会说你的“A”是错误的。 – DavidO

+0

也许这意味着“构造函数不能返回错误,所以通知构造错误的惯用方式是抛出异常”...... – juanchopanza

回答

4

这些注释是错误的,如果他们谈论的是一般的构造函数。 Ctors确实可以正常投掷。也许那是在讨论一个保证非伸缩建筑的特定类?

另一方面,强烈建议您编码,这样您的析构函数永远不会抛出。他们这样做是合法的,但在堆栈展开期间抛出异常会导致程序立即终止(致电std::terminate)。

4

当然,它可以。即使标准容器(例如std::vector)也会从构造函数中抛出std::bad_alloc。这个FAQ说的是实话。

+2

您链接到与OP相同的常见问题解答。 :) – DavidO

+0

@DavidO \t大声笑,我明显需要重述一下这个答案:) – fasked

1

您可以从构造函数中抛出异常,但要小心:如果对象构造不当,析构函数将不会被调用。

class Foo 
{ 
public: 
    Foo(int i) 
    { 
     throw i; 
    } 

    ~Foo() 
    { 
     std::cout << "~Foo()" << std::endl; 
    } 
}; 

int main() 
{ 
    try 
    { 
     Foo f(42); 
    } 
    catch(...) 
    { 
     std::cout << "Catched" << std::endl; 
    } 

    return 0; 
} 

输出:

Catched 

为了解决这个问题,你应该封装一个构造到另一个:

Foo() 
{ 

} 

Foo(int i): Foo() 
{ 
    throw i; 
} 

输出:

~Foo() 
Catched 
+0

尽管析构函数没有执行,但在第一个例子中没有内存泄漏。 (用valgrind观察) – stefan

+0

从来没有没有捕捉所有的条款没有(重新)抛出或你会有一个不好的时间。 – 2013-05-17 16:08:28

+0

@stefan,即使valgrind不显示内存泄漏,在第一种情况下内存将被泄漏。 – soon