C ++ множественное наследование - почему у вас нет работы? - PullRequest
8 голосов
/ 03 мая 2011

Я пытаюсь выяснить интересную проблему множественного наследования.

Дедушка - это интерфейсный класс с несколькими методами:

class A
{
public:
    virtual int foo() = 0;
    virtual int bar() = 0;
};

Затем существуют абстрактные классы, которые частично завершают этоinterface.

class B : public A
{
public:
    int foo() { return 0;}
};

class C : public A
{
public:
    int bar() { return 1;}
};

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

class D : public B, public C
{
public:
    using B::foo;
    using C::bar;
};

Когда я пытаюсь создать экземплярЯ получаю ошибки за попытку создания экземпляра абстрактного класса.

int main()
{
    D d; //<-- Error cannot instantiate abstract class.

    int test = d.foo();
    int test2 = d.bar();

    return 0;
}

Может ли кто-нибудь помочь мне понять проблему и как наилучшим образом использовать частичные реализации?

Ответы [ 2 ]

13 голосов
/ 03 мая 2011

У вас нет наследства алмазов.Каждый из базовых классов B и C из D имеет свой собственный подобъект базового класса A, поскольку они не наследуются виртуально от A.

Так что в D естьна самом деле четыре чистые виртуальные функции-члены, которые необходимо реализовать: A::foo и A::bar из B и A::foo и A::bar из C.

Вы, вероятно, хотите использовать виртуальныенаследование.Объявления классов и списки базовых классов выглядят так:

class A
class B : public virtual A
class C : public virtual A
class D : public B, public C

Если вы не хотите использовать виртуальное наследование, вам нужно переопределить две другие чисто виртуальные функции в D:

class D : public B, public C
{
public:
    using B::foo;
    using C::bar;

    int B::bar() { return 0; }
    int C::foo() { return 0; }
};
0 голосов
/ 03 мая 2011

Вам нужно сделать ваши базовые классы virtual, чтобы они наследовали должным образом.Общее правило заключается в том, что все не приватные функции-члены и базовые классы должны быть virtual, ЕСЛИ ВЫ не знаете, что делаете, и хотите отключить обычное наследование для этого члена / базы.

...