1

初期化リストでコンマ演算子を利用する次のコードがあります。

#include <iostream>

using namespace std;

class Base
{
    protected:
        int b;
    public:
        Base(int a):b(a){}
};

class A:public Base
{
    private:
        const int i;
        const int j;
        void inc(int & a, int & b) {a++; b++;}
    public:
        A(int a, int b):i((inc(a,b),a)),j(b),Base(a+b){}
        void print(){cout<<i<<" "<<j<<" "<<b<<endl;}
};

int main()
{
    A a(6,7);
    a.print();
    return 0;
}

私は結果が次のようになることを期待しています:

7, 8, 15

しかし、次のことが判明しました。

7, 8, 13

基本クラスの構築に使用した場合、「a」と「b」はインクリメントされていないようです。理由がわからない...

4

1 に答える 1

7

メンバー初期化リスト内の項目の順序は、メンバーが初期化される順序を制御しません。基本クラスが最初に初期化され、次に派生クラスのメンバーが定義の順序で初期化されます1

基本クラスが最初に初期化されるため、 は への呼び出しのBase(a+b)に実行され、インクリメントされる前におよびの値が表示されます。incab


  1. c++11、§12.6.2/10:

非委任コンストラクターでは、初期化は次の順序で進行します。

  • まず、最も派生したクラス (1.8) のコンストラクターの場合のみ、仮想基底クラスは、基底クラスの有向非巡回グラフの深さ優先の左から右への走査に現れる順序で初期化されます。 to-right」は、派生クラス base-specifier-list 内の基本クラスの出現順序です。
  • 次に、直接基底クラスは、base-specifier-list に表示される宣言順に初期化されます (mem-initializer の順序に関係なく)。
  • 次に、非静的データ メンバーは、クラス定義で宣言された順序で初期化されます (これも mem-initializer の順序に関係なく)。
  • 最後に、コンストラクター本体の複合ステートメントが実行されます。
于 2013-10-16T04:34:42.727 に答える