web-dev-qa-db-ja.com

C ++:DerivedClassのコンストラクターがBaseClassの保護フィールドにアクセスできないのはなぜですか?

基本クラスのフィールドを初期化しようとするコンストラクターがあります。コンパイラは文句を言う。フィールドは保護されているため、派生クラスがアクセスできる必要があります。

//The base class: 

class BaseClass

{

public:

    BaseClass(std::string);
    BaseClass(const BaseClass& orig);
    virtual ~BaseClass();
    const std::string GetData() const;
    void SetData(const std::string& data);
protected:

    BaseClass();
    std::string m_data;

};

BaseClass::BaseClass(const std::string data) : m_data(data) { }

BaseClass::BaseClass() { } 

BaseClass::BaseClass(const BaseClass& orig) { }

BaseClass::~BaseClass() { }

void BaseClass::SetData(const std::string& data)
{
    m_data = data;
}

const std::string BaseClass::GetData() const
{
    return m_data;
}


//The derived class: 


class DerivedClass : public BaseClass
{

public:

    DerivedClass(std::string data);
    DerivedClass(const DerivedClass& orig);
    virtual ~DerivedClass();
private:

};

DerivedClass::DerivedClass(std::string data) : m_data(data) { } //ERROR HERE

DerivedClass::DerivedClass(const DerivedClass& orig) { }

DerivedClass::~DerivedClass() { }

//コンパイラエラー

DerivedClass.cpp:3:エラー:クラス ‘DerivedClass’には、 ‘m_data’という名前のフィールドがありません

どんな助けでも大歓迎です。前もって感謝します。

32
dwinchell

派生クラスコンストラクターでm_dataを初期化することはできませんが、代わりにそれを引数として基本クラスコンストラクターに渡します。

つまり:DerivedClass::DerivedClass(std::string data) : BaseClass(data) { }

47
Zitrax

初期化リストでは、同じクラスの属性に値を設定するだけです。これにアクセスするには、コンストラクターの本体の値を属性にする必要があります。

DerivedClass :: DerivedClass(s​​td :: string data){m_data = data; }

または、オブジェクトのコピーにコストがかかる場合は、m_dataを引数として親クラスのコンストラクターに渡します。

DerivedClass :: DerivedClass(s​​td :: string data):BaseClass(data){}

ヒント:コピーコンストラクターを防止するために、データを参照として渡します。

詳細はこちらをご覧ください: C++コンストラクターの初期化の順序

8
neves

M_dataに「アクセス」していない-初期化している。ただし、基本クラスのctorですでに初期化されています。値を変更したい場合は、Actorの本文に割り当てます。

DerivedClass::DerivedClass(std::string data) 
{
   m_data = data;
}
4
James Curran

次のように基本クラスコンストラクターを呼び出す必要があります。

DerivedClass::DerivedClass(std::string data) : BaseClass(data) {
}

各クラスは、そのメンバーの初期化を担当する必要があります。

2
code-gijoe

初期化リストは、問題の型が所有するフィールドを初期化するためにのみ使用できます。イニシャライザリストの基本クラスフィールドを初期化することは正しくないため、このエラーが発生します。それ以外の場合、フィールドはDerivedClass内でアクセス可能です

1
JaredPar

派生クラスコンストラクターはアクセスできますが、初期化リストでそれに割り当てることはできません。コンストラクタを次のように変更します。

DerivedClass::DerivedClass(const std::string& data)
 : BaseClass(data)
{
}

または、適切な基本クラスコンストラクターがなく、追加できない場合は、コンストラクターを次のように変更できます。

DerivedClass::DerivedClass(const std::string& data)
{
    m_data = data;
}
0
Will Manley