Проблема множественного наследования в 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()
}
Я прав?
Это похоже на проблему с бриллиантами, но это не так.
Да, это; это классический «ромбовидный» рисунок. Возможно, вы имеете в виду, что проблема не в наличии алмаза? Это, конечно, правда, поэтому мне интересно, почему вы включили эту красную сельдь в вопрос. Вы получите ту же проблему из более простого примера:
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()
должен сделать, и реализовать его соответственно.
Ошибка не в указанной вами строке, а в самом определении класса D
, Определение просто неверно, потому что для виртуальной функции не существует уникального окончательного переопределения.
У вас есть 2 функции с одинаковой сигнатурой из классов B и C, таким образом, функция-член f()
является неоднозначным (что вы уже указали).
Возможно, существует неявное приведение с помощью ap = bp, такое, что ap-> f () будет распознаваться как B :: f, но у dp есть два f () на выбор.
edit: может кто-нибудь объяснить, почему ap-> f () не выдаст ошибку, а dp-> f ()?