Ответ 1
Вы не можете инициализировать m_data в конструкторе производного класса, а вместо этого передать его как аргумент конструктору базового класса.
То есть: DerivedClass::DerivedClass(std::string data) : BaseClass(data) { }
У меня есть конструктор, пытающийся инициализировать поле в базовом классе. Компилятор жалуется. Поле защищено, поэтому производные классы должны иметь доступ.
//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_datap >
Любая помощь приветствуется. Заранее благодарю вас.
Вы не можете инициализировать m_data в конструкторе производного класса, а вместо этого передать его как аргумент конструктору базового класса.
То есть: DerivedClass::DerivedClass(std::string data) : BaseClass(data) { }
В списке инициализаторов вы можете просто установить значения для атрибутов одного и того же класса. Чтобы получить доступ к нему, вы должны атрибут значения в теле конструктора:
DerivedClass:: DerivedClass (std::string data) {m_data = data; }
Или, если это дорого для копирования объекта, вы передаете m_data в качестве аргумента конструктору родительского класса:
DerivedClass:: DerivedClass (std::string data): BaseClass (данные) {}
Совет. Передайте свои данные в качестве ссылки, чтобы предотвратить создание конструктора копии.
Подробнее см. здесь: порядок инициализации конструкторов С++.
Вы не "обращаетесь" к m_data - вы его инициализируете. Однако он уже был инициализирован в базовом классе ctor. Если вы хотите изменить его значение, назначьте его в теле вашего ctor:
DerivedClass::DerivedClass(std::string data)
{
m_data = data;
}
Вам нужно вызвать конструктор базового класса следующим образом:
DerivedClass::DerivedClass(std::string data) : BaseClass(data) {
}
Каждый класс должен отвечать за инициализацию его членов.
Списки инициализаторов могут использоваться только для инициализации полей, принадлежащих данному типу. Неправильно инициализировать поля базового класса в списках инициализаторов, поэтому вы получаете эту ошибку. В противном случае поле доступно в пределах DerivedClass
У вашего конструктора производного класса есть доступ, но вы не можете назначить его в списке инициализации. Измените конструктор на:
DerivedClass::DerivedClass(const std::string& data)
: BaseClass(data)
{
}
В качестве альтернативы, если подходящий конструктор базового класса недоступен, и вы не можете его добавить, вы можете изменить конструктор на:
DerivedClass::DerivedClass(const std::string& data)
{
m_data = data;
}