Nik*_*iou 4 c++ language-lawyer c++11
从相关的c ++标准部分:
引用构造函数的函数try-block的处理程序中的对象的任何非静态成员或基类,或该对象的析构函数导致未定义的行为.
例如.
T::~T()
{
try {
this->nonstatic_member; // iff I read the quote correctly
} catch( ... ) {
}
}
Run Code Online (Sandbox Code Playgroud)
那为什么这个未定义的行为?
我认为在析构函数的函数try-block中访问非静态数据成员的原因是[except.ctor]/2和[except.handle]/11保证所有子对象在进入catch时都已被销毁-clause of try-block:
2014年2月23日的github草案,[except.ctor]/2
任何存储持续时间的对象,其初始化或销毁由异常终止,将为其所有完全构造的子对象(不包括类似联合的类的变体成员)执行析构函数,即对于主构造函数具有的子对象.已完成执行,析构函数尚未开始执行.
[except.handle]/11
[...]在进入该对象的析构函数的function-try-block的处理程序之前,应销毁对象的基类和非变体成员 .
因此,无论我们是在类本身的dtor中还是在子对象的dtor中抛出异常:所有子对象都将被销毁.
#include <iostream>
struct loud
{
~loud() { std::cout << "~loud()\n"; }
};
struct T
{
loud l;
~T() noexcept(false)
try
{
std::cout << "throwing an int\n";
throw 42;
}catch(int)
{
std::cout << "caught an int\n";
throw;
}
};
int main()
{
try
{
T t;
}catch(...)
{
std::cout << "caught an exception in main\n";
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
throwing an int ~loud() caught an int caught an exception in main
#include <iostream>
struct loud
{
loud() { std::cout << "loud()\n"; }
~loud() { std::cout << "~loud()\n"; }
};
struct A
{
A() { std::cout << "A()\n"; }
~A() noexcept(false) { std::cout << "~A()\n"; throw 42; }
};
struct T
{
loud l;
A a;
~T() noexcept(false)
try
{
}catch(int)
{
std::cout << "caught an int\n";
throw;
}
};
int main()
{
try
{
T t;
}catch(...)
{
std::cout << "caught an exception in main\n";
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
loud() A() ~A() ~loud() caught an int caught an exception in main
处理处理程序时,非静态成员可能尚未创建或已被销毁.
并且您的示例未演示函数try-block.当两个子对象都没有被销毁时,它是析构函数体内的一个try-block.
这是构造函数的function-try块的示例
T::T(int ii, double id)
try : i(f(ii)), d(id)
{
// constructor statements
}
catch (...)
{
// handles exceptions thrown from the ctor-initializer
// and from the constructor statements
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
259 次 |
| 最近记录: |