Как исправить «ошибку: нет подходящей функции для вызова» при двойном наследовании от базового класса

В настоящее время я пытаюсь реализовать иерархию унаследованных классов в моем проекте. Поэтому я использую члены 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)
    {
    }
};

Есть идеи?

10000