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’

Любая справка значительно ценится.Заранее спасибо.

29
задан JaredPar 23 July 2010 в 15:56
поделиться

6 ответов

Вы не можете инициализировать m_data в конструкторе производного класса, а передаете его в качестве аргумента в конструктор базового класса.

То есть: DerivedClass::DerivedClass(std::string data) : BaseClass(data) { }

47
ответ дан 28 November 2019 в 01:18
поделиться

В списке инициализаторов вы можете просто установить значения для атрибутов того же класса. Чтобы получить к нему доступ, вы должны атрибутировать значение в теле конструктора:

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

Или, если копировать объект дорого, вы передаете m_data как аргумент конструктору родительского класса :

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

Совет: Передавайте данные как ссылку, чтобы предотвратить конструктор копирования.

Смотрите больше информации здесь: порядок инициализации конструкторов C++

8
ответ дан 28 November 2019 в 01:18
поделиться

Вы не "обращаетесь" к m_data - вы ее инициализируете. Однако он уже инициализирован в ctor базового класса. Если вы хотите изменить его значение, присвойте его в теле вашего ctor:

DerivedClass::DerivedClass(std::string data) 
{
   m_data = data;
}
4
ответ дан 28 November 2019 в 01:18
поделиться

Вам необходимо вызвать базовый класс конструктор следующим образом:

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

Каждый класс должен отвечать за инициализацию своих членов.

2
ответ дан 28 November 2019 в 01:18
поделиться

Списки инициализаторов могут использоваться только для инициализации полей, принадлежащих данному типу. Инициализация полей базового класса в списках инициализаторов недопустима, поэтому вы получаете эту ошибку. В остальном поле доступно в DerivedClass

1
ответ дан 28 November 2019 в 01:18
поделиться

Конструктор производного класса имеет доступ, но вы не можете назначить его в списке инициализации. Измените конструктор на:

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

В качестве альтернативы, если подходящий конструктор базового класса недоступен и вы не можете его добавить, вы можете изменить конструктор на:

DerivedClass::DerivedClass(const std::string& data)
{
    m_data = data;
}
0
ответ дан 28 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: