2017-03-17 69 views
0
template <typename T> 
Blob<T>::Blob(std::initializer_list<T> il) try : 
data(std::make_shared<std::vector<T>>(il)) { 
/* empty body */ 
} catch(const std::bad_alloc &e) { handle_out_of_memory(e); } 

C++入门第五版779页说为什么初始化列表构造函数参数时,异常发生?

Notice that the keyword try appears before the colon that begins the constructor initializer list and before the curly brace that forms the (in this case empty) constructor function body. The catch associated with this try can be used to handle exceptions thrown either from within the member initialization list or from within the constructor body. It is worth noting that an exception can happen while initializing the constructor’s parameters. Such exceptions are not part of the function try block. The function try block handles only exceptions that occur once the constructor begins executing. As with any other function call, if an exception occurs during parameter initialization, that exception is part of the calling expression and is handled in the caller’s context.

我很困惑,不能想到的,当它发生在那里/的情况下,任何人都可以给我 一个例子吗?

+3

从这种情况出发,很难通过“初始化构造函数的参数”知道它们的含义。必须评估* any函数调用的参数,这可能导致异常,尤其是如果这些参数是从函数调用派生的。 –

+0

@MarkRansom我已经添加了更多信息,现在我想你可以知道他们的意思了。 –

+1

你应该改变标题,看起来你是通过成员初始化列表来询问成员的初始化,而不是关于参数初始化。班级成员不是参数 –

回答

2

下面是一个例子:

struct S 
{ 
    S(char *); 
}; 

int main() 
{ 
    S s(new char[0x7FFFFFFF]); 
} 

new char[0x7FFFFFFF]可能会引发内存外的一个例外。

+0

此代码无法编译:错误C2148:数组的总大小不得超过VS2015中的0x7fffffff字节,在VS2010中也一样。 – HDJEMAI

+0

错误:“新”中的数组大小在VS2010中也必须是非负数。 – HDJEMAI

+0

@ H.DJEMAI编辑我的回答 –

0

如果初始化参数时内存不足。

-1

例如:抛出异常:读取访问冲突。

#include <iostream> 

using namespace std; 

class X 
{ 
    int a; 
    int b; 
    int* c; 

    public: 
     X(int a, int b, int* c = nullptr) try : a(a), b(b=c[0]) 
     { 
     } 
     catch (...) 
     { 
      cout << "Exception occured"; 
     } 
}; 

int main() 
{ 
    X v(1,0); 

    return 0; 
} 

Message: c was nullptr.

+1

除以零是未定义的行为;这当然不是这本书的意思。在这种情况下,它是Microsoft编译器的非标准扩展,用于生成未处理的异常 –

+2

您的异常发生在初始化列表中,它在初始化构造函数的参数时不会发生。函数try块可以处理这个。 –

+0

未处理的异常,其中由VS2015和VS2010显示 – HDJEMAI

-1

当一个例外是投一个构造函数调用可能会发生这样的事;隐式或显式。

例如:

class spam { 
public: 
    spam(int eggs) { 
     throw std::exception(); 
    } 
}; 

class foo { 
public: 
    spam unused; 
    const int q; 
    foo() try : unused(1), q(123) { 

    } catch(std::exception& e) { std::cout << "spamspamspam\n";} 
}; 

int main() { 
    try { 
     foo f; // exception thrown 
    } catch (std::exception& e) { 
     std::cout << "It didn't stop there!\n"; 
    } 
    return 0; 
} 

打印在终端上 “!spamspamspam \ n它并没有就此停止\ n”,然后退出与中止。请注意,该异常可以被捕获,但之后会继续传播。这是因为在投掷者之后初始化的任何成员实际上都是而不是已初始化,并且const成员或引用(如const int q在我的示例中)在语法上不可能在稍后的时间点进行初始化。所以答案是完全中止构造函数调用。

+0

thx,你可以理解为什么会发生第二个异常。初始化构造函数的参数时,第一个和第二个异常都不会发生,尽管一个函数try块不能解决问题。这有很大的帮助,我希望你不会删除答案。 –

相关问题