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 ++ Primer第5版779页说
请注意,关键字try出现在开始构造函数的冒号之前 初始化列表和形成(在本例中为空)构造函数的大括号之前 功能体。与此尝试相关联的catch可用于处理异常 从成员初始化列表或构造函数中抛出 身体。 值得注意的是,初始化构造函数时可能会发生异常 参数。此类异常不是函数try块的一部分。功能尝试 块只处理构造函数开始执行后发生的异常。如 与任何其他函数调用一样,如果在参数初始化期间发生异常,那么 exception是调用表达式的一部分,在调用者的上下文中处理。
我很困惑,无法想到发生这种情况的时候,任何人都可以给我 一个例子?
答案 0 :(得分:2)
以下是一个例子:
struct S
{
S(char *);
};
int main()
{
S s(new char[0x7FFFFFFF]);
}
new char[0x7FFFFFFF]
可能会抛出内存异常。
答案 1 :(得分:0)
如果初始化参数时内存不足。
答案 2 :(得分:0)
当构造函数调用中抛出异常时会发生这样的事情;隐式或显式。
例如:
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”然后以中止退出。请注意,可以捕获异常,但之后会继续传播。
这是因为在thrower之后要初始化的任何成员实际上不已初始化,并且const成员或引用(例如我的示例中的 const int q )语法上不可能在以后初始化。所以答案是完全中止构造函数调用。
答案 3 :(得分:-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;
}
消息:c为nullptr。