PODクラスのデフォルトコンストラクタとメンバ変数をprivateにすることでクラスの不変条件を担保する
C++でCと互換性のあるデータ型を使いたい場合は、POD(Plain Old Data)型としなければならない。 C++11 でPODクラスの要件が緩和されたので、PODクラスのメンバ変数やdefaultコンストラクタをprivate に定義できるようになった。 これにより、PODクラスでもコンストラクタでクラスの不変条件を担保できる。
C++11 でのPODクラスの要件
C++ concepts: PODType - cppreference.com から引用。
a trivial type;
a standard layout type;
has no non-static members that are non-POD;
POD クラスに対する不変条件の強制
上記要件さえ満たしていれば、メンバ変数がprivate でもいい。また、trivial class の要件はデフォルトコンストラクタがtrivial であることなので、privateかつ default 指定でデフォルトコンストラクタを定義すれば良い。
#include <type_traits> #include <stdexcept> struct A { private: int a_; // メンバがprivate でもいい. A() = default; // デフォルトコンストラクタがprivateでも default 定義であればいい. public: // デフォルトコンストラクタがtrivial なら他のコンストラクタがあってもいい. A(int a) : a_(a){ // メンバ a_ は非負という条件を強制. if(a_ < 0){ throw std::invalid_argument("a must not be negative"); } } }; static_assert(std::is_pod_v<A>); // A は POD.
なお、C++20 では PODという概念は deprecated になる模様。