35

I have a constructor attempting to initialize a field in a base class. The compiler complains. The field is protected, so derived classes should have access.

//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() { }

//The compiler error

DerivedClass.cpp:3: error: class ‘DerivedClass’ does not have any field named ‘m_data’</p>

Any help is greatly appreciated. Thank you in advance.

4

6 に答える 6

54

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

あれは:DerivedClass::DerivedClass(std::string data) : BaseClass(data) { }

于 2010-07-23T15:56:49.380 に答える
10

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

DerivedClass::DerivedClass(std::string data) {m_data = データ; }

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

DerivedClass::DerivedClass(std::string データ) : BaseClass(データ) {}

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

ここで詳細情報を参照してください: C++ コンストラクターの初期化の順序

于 2010-07-23T16:00:05.813 に答える
4

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

DerivedClass::DerivedClass(std::string data) 
{
   m_data = data;
}
于 2010-07-23T16:00:15.957 に答える
2

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

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

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

于 2010-07-23T16:01:21.650 に答える
1

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

于 2010-07-23T15:59:48.783 に答える
0

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

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

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

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

于 2010-07-23T16:00:30.357 に答える