p_tan's blog

勉強日記です。ツッコミ大歓迎

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 になる模様。