В настоящее время я пытаюсь реализовать иерархию унаследованных классов в моем проекте. Поэтому я использую члены initializer-lists и "pipe" - ссылку на переменную вплоть до базового класса. Я действительно не уверен, почему я получаю ошибку компилятора.
Я уже пытался изменить ссылку "int & id" на указатель "int * id". Приведенный ниже пример является лишь минимальным примером, который указывает на мою проблему:
class Base { public: int& m_id; Base(int &id) : m_id(id) { } }; class Derived1: virtual public Base { public: Derived1(int &id) : Base(id) { }; }; class Derived2: public Derived1 { public: Derived2(int &id) : Derived1(id) { }; }; int main() { int i = 13; Derived2 Test(i); }
Я получаю следующее сообщение об ошибке при попытке компиляции:
msgstr "ошибка: нет подходящей функции для вызова Base :: Base ()"
Есть идеи, что я делаю не так?
Спасибо за вашу помощь.
Всего 2 ответа
Виртуальное наследование и виртуальные функции - разные понятия.
Виртуальное наследование отличается тем, что виртуальные базы должны быть явно инициализированы всеми производными классами. В этом случае Derived2
пытается делегировать инициализацию Base
для Derived1
, но это недопустимо. Что фактически делает конструктор Derived2
, так это вызывает конструктор Base
по умолчанию из-за отсутствия инициализатора mem, который инициализирует Base
.
Вы должны явно вызвать конструктор Base
:
class Derived2 :public Derived1 {
public:
Derived2(int &id) : Base(id), Derived1(id)
{
};
};
Конечно, если Derived1
не должен был быть производным от Base
, то производные классы Derived1
могут просто полагаться на конструктор Derived1
для инициализации Base
. Таким образом, другое исправление, в зависимости от вашей ситуации, состоит в том, чтобы просто удалить virtual
в спецификаторе базы :
class Derived1 :public Base {
public:
Derived1(int &id) :Base(id)
{
};
};
class Derived2: public Derived1 {
public:
Derived2(int &id) :Derived1(id)
{
};
};
Виртуальное наследство странный зверь. Это требует, чтобы самый производный класс инициализировал виртуальные базовые классы. В вашем случае эта инициализация отсутствует. Это должно сделать это:
class Derived2: public Derived1
{
public:
Derived2(int &id) : Base(id), Derived1(id)
{
}
};