множественное наследование в C ++, это похоже на алмаз, но это не так

Проблема множественного наследования в C ++:

Это похоже на проблему с бриллиантами, но это не так. Это не может быть решено путем добавления виртуального наследования.

struct A {
virtual void f() { cout << "A::f()" << endl; };
};

struct B : public virtual A {
void f() { cout << "B::f()" << endl;};
};

struct C :  public virtual A {
void f() { cout << "C::f()" << endl;};
};

struct D : B, C { };

int main() {
D d;

B* bp = &d;
A* ap = bp;
D* dp = &d;

ap->f();
dp->f(); // compile error here because D has two candidates f() to override.
// error: request for member f is ambiguous
// error: candidates are: virtual void C::f()
// error:                 virtual void B::f()

}

Я прав?

1

Решение

Это похоже на проблему с бриллиантами, но это не так.

Да, это; это классический «ромбовидный» рисунок. Возможно, вы имеете в виду, что проблема не в наличии алмаза? Это, конечно, правда, поэтому мне интересно, почему вы включили эту красную сельдь в вопрос. Вы получите ту же проблему из более простого примера:

struct B {
virtual void f() { cout << "B::f()" << endl;};
};

struct C {
virtual void f() { cout << "C::f()" << endl;};
};

struct D : B, C { };

ошибка компиляции здесь, потому что у D есть два кандидата f () для переопределения.

Нет, ошибка в том, что D не переопределяет их, поэтому для вызова функции есть два кандидата. Виртуальная функция переопределяется в обоих прямых базовых классах, но не в производном классе, поэтому не существует уникального окончательного переопределения.

Вам нужно решить, что D::f() должен сделать, и реализовать его соответственно.

4

Другие решения

Ошибка не в указанной вами строке, а в самом определении класса D, Определение просто неверно, потому что для виртуальной функции не существует уникального окончательного переопределения.

0

У вас есть 2 функции с одинаковой сигнатурой из классов B и C, таким образом, функция-член f() является неоднозначным (что вы уже указали).

0

Возможно, существует неявное приведение с помощью ap = bp, такое, что ap-> f () будет распознаваться как B :: f, но у dp есть два f () на выбор.

edit: может кто-нибудь объяснить, почему ap-> f () не выдаст ошибку, а dp-> f ()?

-1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector