145

子クラスのコンストラクターの初期化リストを使用して、親クラスで保護されていると宣言されたデータ メンバーを初期化することは可能ですか? 私はそれを働かせることができません。私はそれを回避することができますが、そうする必要がなければいいでしょう。

サンプルコード:

class Parent
{
protected:
    std::string something;
};

class Child : public Parent
{
private:
    Child() : something("Hello, World!")
    {
    }
};

これを試してみると、コンパイラは「クラス 'Child' には 'something' という名前のフィールドがありません」と教えてくれます。このようなことは可能ですか?もしそうなら、構文は何ですか?

どうもありがとう!

4

5 に答える 5

139

あなたが説明する方法では不可能です。それを転送するには、基本クラスにコンストラクター (保護されている可能性があります) を追加する必要があります。何かのようなもの:

class Parent
{
protected:
    Parent( const std::string& something ) : something( something )
    {}

    std::string something;
}

class Child : public Parent
{
private:
    Child() : Parent("Hello, World!")
    {
    }
}
于 2010-02-18T17:33:02.580 に答える
72

コンパイラが初期化子リストに遭遇したとき、派生クラス オブジェクトはまだ形成されていません。それまで、基本クラスのコンストラクターは呼び出されていません。基本クラスのコンストラクターが呼び出された後にのみ、something存在するようになります。したがって、問題。基本クラスのコンストラクターを明示的に呼び出さない場合は、コンパイラーが (基本クラスの適切な単純なコンストラクターを生成することによって) 呼び出します。これにより、somethingメンバーがデフォルトで初期化されます。

C++0x ドラフトから:

12.6.2 ベースとメンバーの初期化

2 mem-initializer-id の名前は、コンストラクターのクラスのスコープで検索され、そのスコープで見つからない場合は、コンストラクターの定義を含むスコープで検索されます。[注: コンストラクターのクラスに、クラスの直接または仮想基底クラスと同じ名前のメンバーが含まれている場合、メンバーまたは基底クラスに名前を付け、単一の識別子で構成される mem-initializer-id は、クラス メンバーを参照します。非表示の基本クラスの meminitializer-id は、修飾名を使用して指定できます。--end note ] mem-initializer-id がコンストラクターのクラス、コンストラクターのクラスの非静的データ メンバー、またはそのクラスの直接または仮想ベースを指定しない限り、mem-initializer は不適切な形式です。

注:私のものを強調してください。

于 2010-02-18T17:40:10.330 に答える
18

派生クラス コンストラクターの初期化リストで、親クラスのメンバーを初期化することはできません。それらが保護されているか、公開されているか、またはその他のものであるかは問題ではありません。

あなたの例では、メンバーsomethingParentクラスのメンバーです。つまり、クラスのコンストラクター初期化子リストでのみ初期化できますParent

于 2010-02-18T17:35:16.343 に答える