class 不可抛出构造但不可抛出破坏
class is not nothrow constructible but is nothrow destructible
我有一个 class 如下所示:
#include <iostream>
#include <type_traits>
#include <concepts>
#include <vector>
class Foo
{
public:
Foo( )
: m_member1( 1 ), m_member2( 2 ), m_member3( std::vector<char>( 1 * 2, '-' ) )
{
}
// ~Foo( ) is not defined (i.e. implicitly declared by the compiler)
private:
int m_member1;
int m_member2;
std::vector<char> m_member3;
};
int main( )
{
std::cout << std::boolalpha << "is nothrow constructible? " << std::is_nothrow_constructible_v<Foo> << '\n'
<< "is nothrow destructible? " << std::destructible<Foo> << '\n';
}
在上面的代码中,我利用了 C++20 概念 (std::destructible<T>
) 来获取有关上述 class.
的更多信息
输出:
is nothrow constructible? false
is nothrow destructible? true
我明白为什么它不可构造。例如。 std::vector
的构造函数可以抛出 std::bad_alloc
,等等。但是为什么析构函数 也不会抛出 ?
现在,如果隐式析构函数是 nothrow,那么如果我将析构函数标记为 noexcept
以防我写一个显式定义,会不会更好?
析构函数很特别。对于隐式析构函数以及没有 noexcept
规范的用户声明的析构函数,如果成员和基 类 的所有析构函数都是 noexcept(true)
.[=,则析构函数默认为 noexcept(true)
15=]
要获得潜在抛出的析构函数,您需要显式声明它noexcept(false)
。然而,这通常不是人们想要的,因为如果在从另一个异常中展开堆栈时析构函数抛出,将会出现问题。
对于普通函数,通常默认为noexcept(false)
,意思是潜在抛出,如果没有另外声明的话。
不过,还有一些此类特殊情况,例如解除分配函数和(成员)函数在第一次声明时默认。
我有一个 class 如下所示:
#include <iostream>
#include <type_traits>
#include <concepts>
#include <vector>
class Foo
{
public:
Foo( )
: m_member1( 1 ), m_member2( 2 ), m_member3( std::vector<char>( 1 * 2, '-' ) )
{
}
// ~Foo( ) is not defined (i.e. implicitly declared by the compiler)
private:
int m_member1;
int m_member2;
std::vector<char> m_member3;
};
int main( )
{
std::cout << std::boolalpha << "is nothrow constructible? " << std::is_nothrow_constructible_v<Foo> << '\n'
<< "is nothrow destructible? " << std::destructible<Foo> << '\n';
}
在上面的代码中,我利用了 C++20 概念 (std::destructible<T>
) 来获取有关上述 class.
输出:
is nothrow constructible? false
is nothrow destructible? true
我明白为什么它不可构造。例如。 std::vector
的构造函数可以抛出 std::bad_alloc
,等等。但是为什么析构函数 也不会抛出 ?
现在,如果隐式析构函数是 nothrow,那么如果我将析构函数标记为 noexcept
以防我写一个显式定义,会不会更好?
析构函数很特别。对于隐式析构函数以及没有 noexcept
规范的用户声明的析构函数,如果成员和基 类 的所有析构函数都是 noexcept(true)
.[=,则析构函数默认为 noexcept(true)
15=]
要获得潜在抛出的析构函数,您需要显式声明它noexcept(false)
。然而,这通常不是人们想要的,因为如果在从另一个异常中展开堆栈时析构函数抛出,将会出现问题。
对于普通函数,通常默认为noexcept(false)
,意思是潜在抛出,如果没有另外声明的话。
不过,还有一些此类特殊情况,例如解除分配函数和(成员)函数在第一次声明时默认。