派生类构造函数上的Noexcept promise:可以在没有对基构造函数上的Noexcept进行承诺的情况下使用
Noexcept promise on derived class constructor: can that be used without promising noexcept on base constructor?
假设我有一个类
class C : public B {
public:
C() noexcept;
}
noexcept
说明符是否需要基类提供相同的promise?也就是说,当我考虑使用noexcept时,我是只看C::C()的行为,还是还需要考虑B::B()是否会抛出异常?
例如,如果B::B抛出异常,它会传播到C::C还是传播到请求新类实例的代码?——如果传播到C::C,如果基类不是构造函数的noexcept,那么这将是避免构造函数的noxcept的原因之一。
从技术上讲,†没有要求基类构造函数声明为noexcept,但当被声明为noxcept的派生构造函数调用时,它不能抛出。
因此,是的,您确实需要考虑基类构造函数是否会抛出(异常或其他)。
我想问我这个问题的一个更好的方法是:例外下一步会去哪里?
呼叫流程如下:
caller
-> derived constructor (the noexcept applies to this)
-> subobject constructors (includes bases)
- derived constructor body (not a call, but part of the derived constructor that is executed after the subobjects are constructed)
因此,如果子对象(无论是基构造函数还是成员构造函数)构造函数抛出,它首先进入派生构造函数,派生构造函数不会也不能††吞下异常,因此如果构造函数不是noexcept,它将传播到调用方。但既然如此,std::terminate
就会被调用。
†如果基类确实没有按照派生类的要求抛出,那么它确实满足了要求,并且本身可以被声明为noexcept,所以很少有理由不这样做。也许,如果基类是必须支持c++03的库的一部分,而派生类可能会采用更晚的标准,这是有意义的。
††它可以用函数try块捕获,但这些块总是会再次抛出。
相关文章:
- 为什么 std::map 的移动构造函数不是 noexcept?
- 查找所有移动构造函数和移动赋值运算符(特别是那些没有"noexcept"的运算符)
- 为什么noexcept move构造函数在向量重新分配期间没有被调用
- MSVC 2017中STL容器的移动构造函数未标记为NOExcept
- 对于具有抛出复制构造函数和noexcept-by-value复制赋值的类,is_nothrow_copy_assigna
- 是复制构造函数中初始值设定项列表中的make_unique不使用noexcept说明符的好用途
- 在向量中使用不带复制且没有 noexcept 移动构造函数的对象.实际损坏的内容以及我如何确认它
- is_nothrow_default_constructible具有noexcept(false)默认构造函数
- 如何声明包装器类型 X 的移动构造函数<T> noexcept 取决于is_nothrow_move_constructible<T>?
- 为什么 g++ 不发出这个与构造函数相关的 noexcept 启用"-fpic"的警告?
- 我应该声明我的异常的副本构造函数noexcept吗
- 具有 GCC 接受"noexcept"构造函数的程序,被 clang 拒绝
- 派生类构造函数上的Noexcept promise:可以在没有对基构造函数上的Noexcept进行承诺的情况下使用
- 对于默认定义的移动构造函数,noexcept的规则是什么
- 从 noexcept 函数参数的构造函数引发的异常会立即导致对 std::terminate() 的调用吗?
- 默认情况下是默认的构造函数/赋值noexcept/constexpr
- 默认情况下继承构造函数 noexcept(true)
- 确定抽象基类的构造函数是否为 noexcept
- 编译器何时将默认生成的构造函数标记为 noexcept
- 为什么noexcept构造函数需要析构函数的实例化