Почему в коде ниже компилятор жалуется, что PureAbstractBase
является двусмысленным базовым классом MultiplyInheritedClass
? Я понимаю, что у меня две копии PureAbstractBase
в MultiplyInheritedClass
и что FirstConreteClass
и SecondConreteClass
должны быть получены практически потому, что они представляют собой средний ряд алмаза (и это действительно исправляет проблему с помощью кода ниже). Но хотя у меня есть две копии интерфейса, почему код в MultiplyInheritedClass
не просто переопределяет оба и недвусмысленно выбирает класс интерфейса, определенный в MultiplyInheritedClass
?
#include <iostream>
using namespace std;
class PureAbstractBase {
public:
virtual void interface() = 0;
};
// I know that changing the following line to:
// class FirstConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class FirstConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object FirstConcreteClass\n"; }
};
// I know that changing the following line to:
// class SecondConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class SecondConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object SecondConcreteClass\n"; }
};
class MultiplyInheritedClass : public FirstConcreteClass,
public SecondConcreteClass {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object MultiplyInheritedClass\n"; }
};
Кроме того, почему у меня нет проблем со следующей иерархией? В этом случае класс ConcreteHandler не имеет трех экземпляров AbstractTaggingInterface? Так почему же у него нет такой же проблемы, как в примере выше?
#include <iostream>
using namespace std;
class AbstractTaggingInterface {
public:
virtual void taggingInterface() = 0;
};
class FirstAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "FirstAbstractHandler\n"; }
virtual void handleFirst() = 0;
};
class SecondAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "SecondAbstractHandler\n"; }
virtual void handleSecond() = 0;
};
class ThirdAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "ThridAbstractHandler\n"; }
virtual void handleThird() = 0;
};
class ConcreteHandler : public FirstAbstractHandler,
public SecondAbstractHandler,
public ThirdAbstractHandler {
public:
virtual void taggingInterface() = { cout << "ConcreteHandler\n"; }
virtual void handleFirst() {}
virtual void handleSecond() {}
virtual void handleThird() {}
};
Я пытаюсь обвести вокруг себя все это, потому что недавно у меня был разговор с коллегой, где он утверждал, что если вы наследовали из чистых виртуальных классов (интерфейсов) без каких-либо элементов данных, тогда виртуальное наследование не было необходимым. Я думаю, что понимание того, почему пример бывшего кода не работает, и последнее делает долгий путь, чтобы получить это прямо в моей голове (и выяснить, что именно он имел в виду под своим комментарием). Заранее спасибо.