2011-04-21 161 views
14

这是我的一个面试问题。处理构造函数的异常

令人惊讶的是,我从来没有想过给自己一个这样的问题。

我们可以在构造函数C++中有异常处理吗?

现在时态并没有多想我说“是的,我们可以做一个constructor.lets说我们正在使用new运算符分配一些内存到一个指针成员,它会抛出一个错误的alloc异常,这样就有可能会有异常提出“

然后后来我认为构造函数永远不会返回一个值。那么构造函数中的异常怎么会被抓到。现在我问这个问题了!

有人能帮我摆脱这种困惑吗?

+0

你会捕获该异常调用代码,而不是在构造函数中。 – helpermethod 2011-04-21 10:48:10

+3

异常不会以与返回值相同的方式返回,它们将堆栈跳到第一个适当的catch块,因此尽管您无法从构造函数返回值,但可以从中引发异常。 – forsvarir 2011-04-21 10:50:30

+0

@Helper方法:如果您在构造函数中分配了内存,您肯定会想要在构造函数中捕获异常,以便您可以取消分配内存(然后重新抛出)。但更智能的是让对象只动态分配一个对象,所以你不需要执行这种手动清理。 – 2011-04-21 11:17:21

回答

12

看到这个GOTW Constructor Failures问题哪些地址您的查询有点并继续说这是浪费时间。

+3

+1我打算写一个关于function-try-block的选项和它的许多缺陷,但我不会接近Sutter的描述:) – 2011-04-21 10:57:17

+0

这是一篇非常有趣的文章,def + 1 – Justin 2011-04-21 19:15:04

-2

C++具有类似于其他语言的try-catch子句。该教程可以在网上查到:http://www.cplusplus.com/doc/tutorial/exceptions/

编辑:例如变成完全的工作代码

#include <iostream> 
using namespace std; 

class A 
{ 
public: 
    void f(){ 
    throw 10; 
    } 

    A(){ 
    try{ 
     f(); 
    } 
    catch(int e){ 
     cout << "Exception caught\n"; 
    } 
    } 
}; 

int main (int argc, const char * argv[]) 
{ 

    A a; 
    return 0; 
} 

这将产生输出:

Exception caught 
+0

@ laas.i知道有很多documents.But我特别要求在构造函数中的异常处理。这并不代表我的问题。 – Vijay 2011-04-21 10:50:09

+0

C++没有'finally'块,并且C++中的异常处理在许多方面与Java等语言有所不同,例如对于清理,C++使用http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization – helpermethod 2011-04-21 10:53:14

+0

@Helper方法 - 你当然是对'finally'正确的,但据我了解,@ zombie询问**构造函数内的异常处理**,所以我的示例仍然有效,或者应该纠正问题。我用更多的代码更新我的答案。 – Laas 2011-04-21 11:27:45

2

构造函数没有返回类型, 所以不可能使用返回码 。 构造函数失败的最好方法是因此给 抛出异常。如果你没有 使用异常的选项, “最不坏”的解决办法是把 对象变成“僵尸”状态由 设置内部状态位使 对象的行为有点像它的尽管它在技术上仍然 活着,但它仍然死亡。

你会赶上调用代码例外,而不是在构造函数中。

查看How can I handle a constructor that fails?了解更多详情(实际上,我建议阅读关于异常处理的整个页面,真正有启发性)。

+0

我读过这篇文章,但我期待人们在这种场景中使用的一些实用方法。 – Vijay 2011-04-21 10:51:31

+1

+1,但人们必须说这个问题也有点棘手。通常,当你以某种方式在构造函数中失败时,它就会抛出一个构造函数,这完全可以在构造函数中尝试/捕获以处理其他失败并避免构造函数首先失败(或重新抛出)。根据情况,这可能是可取的。例如,如果在构造函数中构造两个对象,并且第二个引发bad_alloc,那么你会怎么做?捕获调用代码中的异常将泄漏第一个对象。在构造函数内处理避免了这一点。 – Damon 2011-04-21 10:56:53

+0

@ zombie:有什么场景?从构造函数中抛出异常?构造函数失败?一个捕获异常的构造函数? – forsvarir 2011-04-21 10:57:21

0

异常处理和返回类型完全不同。当程序在构造函数中发现异常时,它会通过catch块[如果使用]或抛出调用方(main())将该异常抛出。在这种情况下,我们在构造函数和异常处理中都有catch块。一旦处理异常,构造函数/函数中的其余语句将开始执行。看下面的例子,

class A 
{ 
    public: 
    A(){ 
     printf("Hi Constructor of A\n");   
    try 
    { 
     throw 10; 
    } 
    catch(...) 
    { 
     printf("the String is unexpected one in constructor\n"); 
    } 
    printf("Hi Constructor of A\n"); 
} 
    ~A(){ 
    printf("Hi destructor of A\n"); 
} 
}; 

int main() 
{ 

try{ 
    A obj ; 
    throw "Bad allocation"; 
} 
catch(int i) 
{ 
    printf("the Exception if Integer is = %d\n", i); 
} 
catch(double i) 
{ 
    printf("the Exception if double is = %f\n", i); 
} 
catch(A *objE) 
{ 
    printf("the Exception if Object \n"); 
} 
catch(...) 
{ 
    printf("the Exception if character/string \n"); 
} 
printf("Code ends\n"); 
return 0; 
} 

这产生输出:

Start: Constructor of A 
the String is unexpected one in constructor 
End: Constructor of A 
Hi destructor of A 
the Exception if character/string 
Code ends