C++メンバーとベースクラスの初期化


C++メンバーとベースクラスの初期化
class Club
{
    struct Date
    {
        int year;
        int month;
        int day;
        Date(int y, int m, int d);
    }

    string name;
    vector<string> members;
    vector<string> officers;
    Date founded;
public:
    Club(const string& n, Date fd);
};

1.メンバーの初期化
Clubのコンストラクション関数は2つのパラメータを受信します.コンストラクション関数の定義では、メンバーのコンストラクション関数のパラメータを で指定します.
Club::Club(const string& n, Date fd)
    :name{n},founded{fd}
{
    // ...
}
                ,                 。
  • クラス自体のコンストラクション関数は、そのコンストラクション関数体が実行される前にメンバーのコンストラクション関数を呼び出す.メンバーのコンストラクション関数は、初期化リストにメンバーが表示される順序ではなく、クラス内のメンバーの宣言順に呼び出されます.
  • 組み込み型メンバーは明示的に初期化する必要があり、暗黙的に初期化された組み込み型メンバーは実際には初期化されていない
  • である.
  • コンストラクション関数は、クラスのメンバーおよびベースクラスを初期化できますが、 です.すなわち、クラスのメンバーの初期化プロセスは、1つのレベルのメンバー(自分のメンバーを呼び出すコンストラクション関数)のみを初期化し、メンバーのメンバー(自分のメンバーを呼び出すコンストラクション関数)
  • は初期化しません.
  • 参照メンバーまたはconstメンバーは、
  • を初期化する必要があります.
    2.ベースクラスイニシエータ
    ベースクラスに初期化器が必要な場合は、コンストラクション関数に対応するベースクラスの初期化器を指定する必要があります.デフォルトの構造を行う場合は、明示的に示すことができます.
    class B1{ B1(); };        //         
    class B2{ B2(int); };     //        
    
    struct D1 : B1,B2
    {
        D1(int i) : B2{i}{}   //     B1{}
    };
    
    struct D2 : B1,B2
    {
        D2(int i){}           //   :B2      ,     int    
    };

    ベースクラスは宣言順に初期化されます.この順序でベースクラスの初期化器を指定することをお勧めします.ベースクラスの初期化はメンバーの前に行われ、メンバーの後に破棄されます.
    3.委託構築関数
    class X
    {
        int a;
    public:
        X(int x){ if (0else throw Bad_X(x); }
        X() : X{42} {}
        X(string s) : X{to<int>(s)} {}
        // ......
    };

    メンバースタイルの初期化器を使用しますが、クラス自体の名前(コンストラクション関数名でもあります)を使用すると、このコンストラクションプロセスの一部として別のコンストラクション関数が呼び出されます.
    4.クラス内イニシエータ
    クラス宣言でstatic以外のデータ・メンバーのイニシエータを指定できます.
    class A
    {
    public:
        int a{7};
        int b=77;
    };
    {} =             , ()     
    

    デフォルトでは、コンストラクション関数はこのクラス内の初期化器を使用します.上記のコード効果と等価なものは次のとおりです.
    class A
    {
    public:
        int a;
        int b;
        A() : a{7},b{77} {}
    };

    クラス内の初期化器のこの使用は、入力ワークロードを節約できますが、実際の収益は、複数の構造関数を持つ複雑なクラスで使用される場合、同じメンバーに対して複数の構造関数が通常同じ初期化器を使用することです.1つのメンバーがクラス内の初期化器で初期化され、コンストラクション関数で初期化された場合、後者のみの初期化操作が実行されます.
    5.staticメンバー初期化
    一般的に、staticメンバー宣言はクラス外定義の宣言として機能します.
    class Node
    {
        //......
        static int node_count;    //   
    }
    
    int Node::node_count = 0;     //   

    しかし、少数の単純な特殊な場合、クラス内宣言でstaticメンバーを初期化することも可能である.条件はstaticメンバーが整数または列挙タイプのconst、またはフォント値タイプのconstexprである必要があり、初期化器は定数式である必要があります.
    class Curious
    {
    public:
        static const int c1 = 7;        //   
        static int c2 = 11;             //   : const
        const int c3 = 13;              //   ,  static
        static const int c4 = sqrt(9);  //   :          
        static const float c5 = 7.0;    //   :           (   constexpr  const)
    }

    初期化されたメンバーを使用してオブジェクトのようにメモリに格納するように要求された場合、そのメンバーはどこか(一意)で定義する必要があります.初期化器は繰り返しません.