C++: Why does my DerivedClass's constructor not have access to the BaseClass's protected field?

自古美人都是妖i 提交于 2019-11-29 00:31:56

问题


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’

Any help is greatly appreciated. Thank you in advance.


回答1:


You cannot initialize m_data in the derived class constructor but instead pass it as an argument to the base class constructor.

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




回答2:


In the initializer list you can just set values for attributes of the same class. To access it, you must attribute the value in the body of the constructor:

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

Or, if it is expensive to copy the object, you pass the m_data as an argument to the parent class constructor :

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

Tip: Pass your data as a reference to prevent the copy constructor.

See more info here: order of initialization of C++ constructors.




回答3:


You are not "accessing" m_data -- you are initializing it. However, it's already been initialized in the Base Class's ctor. If you want to change it's value, assign to it in the body of your ctor:

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



回答4:


You need to call the base class constructor as follows:

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

Each class should be in charge of initializing it's members.




回答5:


Initializer lists can only be used to initialize fields which are owned by the type in question. It is not legal to initialize base class fields in an initializer lists which is why you receive this error. The field is otherwise accessible within DerivedClass




回答6:


Your derived class constructor does have access, but you cannot assign to it in the initialisation list. Change the constructor to:

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

Alternatively, if no suitable base class constructor is available and you cant add one you can change the constructor to:

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


来源:https://stackoverflow.com/questions/3319892/c-why-does-my-derivedclasss-constructor-not-have-access-to-the-baseclasss-p

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!