У меня трудное время с проблемой страшного алмаза. Для напоминания, здесь иерархия классического класса этой проблемы:Виртуальное наследование и страшный бриллиант
B
/\
C1 C2
\/
D
Чтобы решить эту проблему, стандартное решение сделать C1 и C2 использовать виртуальное наследование наследования от B.
Моей проблемы заключается в том, что B и C1 являются SDK, которые я не могу изменить. Пример ниже, где я не могу сделать SubClassB Наследовать практически от База. Классы: PureVirtualBase, Base и SubClassB - из используемого SDK. Я не могу их изменить. SubClassA и Leaf - мои пользовательские классы. Я могу их изменить.
PureVirtualBase(SDK)
|
Base(SDK)
/ \
SubClassA SubClassB(SDK)
\ /
Leaf
В такой ситуации, когда SubClassB не может быть изменен, чтобы использовать виртуальное наследование от базы. Как что должно, так что:
- Leaf экземпляр содержит только один Base
- Избегайте двусмысленности при попытке доступа к функциям определяется чисто виртуальным в PureVirtualBase и реализован в базе
class PureVirtualBase
{
public:
PureVirtualBase()
{
cout<<"<<PureVirtualBase::PureVirtualBase" << endl;
cout<<">>PureVirtualBase::PureVirtualBase" << endl;
}
virtual int f_PureVirtualBase()=0;
};
class Base : public PureVirtualBase
{
public:
Base(std::string id) {
cout<<"<<Base::Base:"<<id << endl;
m_id=id;
cout<<">>Base::Base:"<<m_id << endl;
}
virtual int f_PureVirtualBase() {
cout<<"Base::f_PureVirtualBase" << endl;
return 1;
}
private:
std::string m_id;
};
class SubClassA: public virtual Base
{
public:
SubClassA(): Base("From SubClassA") {
cout<<"<<SubClassA::SubClassA" << endl;
cout<<">>SubClassA::SubClassA" << endl;
}
};
class SubClassB: public Base
{
public:
SubClassB():Base("From SubClassB") {
cout<<"<<SubClassB::SubClassB" << endl;
cout<<">>SubClassB::SubClassB" << endl;
}
};
class Leaf: public SubClassA, public SubClassB
{
public:
Leaf():SubClassA(), SubClassB(), Base("From Leaf") {
cout << "<<Leaf::Leaf" << endl;
cout << ">>Leaf::Leaf"<< endl;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Leaf myleaf;
myleaf.f_PureVirtualBase();
return a.exec();
}
- Если я комментирую вызов f_PurevirtualBase компилирует, но у меня есть предупреждение, что виртуальная база «База» недоступна в «Лист» из-за неоднозначности Если я раскомментировать этот вызов: Я получаю эту ошибку: запрос для члена ' f_PureVirtualBase»неоднозначен
- Если я префикс этого вызова по имени класса (myleaf.SubClassA :: f_PureVirtualBase(), то она работает, но что-то , очевидно, не так, как есть 2 Base содержится в Leaf Объект).
Подсказка?
Более подробную информацию, чтобы ответить на комментарии
Моя целевая архитектура немного более сложным, что образец я представил в оригинальный вопрос:
PureVirtualBase(SDK)
|
Base(SDK)
|
--SubClassA
--SubClassB(SDK)
--SubClassC(SDK)
--SubClassD(SDK)
LeafOne: наследуется от SubClassA и SubClassB (SDK)
LeafTwo: наследуется от SubClassA и SubClassC (SDK)
LeafThree: наследуется от SubClassA и SubClassD (SDK)
SubClassA - это мой личный код. Он предоставляет пользовательские функции. Он должен быть обработан как пример базы с помощью SDK-методов. Этот класс не будет создан, но он здесь, чтобы иметь возможность обрабатывать LeafOne, LeafTwo и LeafThree в то же время при выполнении некоторых процедур.
Как насчет одного унаследованного класса и другого составного. – iammilind
Это то, что я рассматриваю, но интеграция такого класса Leaf не была бы столь же изящной в нашем SDK, и много разных проблем придется решать. Тем не менее, вы правы, это единственный способ решить эту проблему, но я бы хотел найти способ сделать это, хотя наследование упростило интеграцию с функциями SDK. – Marc
Почему вы думаете, что 'SubClassA' должен наследовать от' Base' вообще? Учитывая определение «SubClassB», очевидно, что «Base» не является виртуальным базовым классом в иерархии, которая включает в себя «SubClassB». –