CppCoreGuidelines C.44 默认构造函数尽量简单且不要抛出异常
08 October 2022
“Prefer default constructors to be simple and non-throwing”
理由
无需额外的、会报错的操作,就能设定默认值,可以简化错误处理的过程和移动操作的推演。
错误例子
template<typename T> // elem points to space-elem element allocated using new class Vector0 { public: Vector0() :Vector0{0} {} Vector0(int n) :elem{new T[n]}, space{elem + n}, last{elem} {} // ... private: own<T*> elem; T* space; T* last; };
这个类定义看起来挺不错,但是给 Vector0 设定空值的时候,也可能由于内存分配出错。另外,用 {new T[0], 0, 0} 这样的方式来表示默认 Vector 看起来很浪费。比如, Vector0<int> v[100] 会导致 100 次内存分配。
例子
template<typename T> // elem is nullptr or elem points to space-elem element allocated using new class Vector1 { public: // sets the representation to {nullptr, nullptr, nullptr}; doesn't throw Vector1() noexcept {} Vector1(int n) :elem{new T[n]}, space{elem + n}, last{elem} {} // ... private: own<T*> elem {}; T* space {}; T* last {}; };
用 {nullptr, nullptr, nullptr} 表示 Vector1{} 更节省资源,而且这种特殊情况意味着运行时检查,防止出错。如果检测到错误,把 Vector1 设定为空比较简单。
强化
- 标记会抛出异常的构造函数