Иерархия множественного наследования - PullRequest
2 голосов
/ 18 июня 2009

Я давно ищу чистый способ сделать это. В моей проблеме существует 3 класса, которые не имеют общих родителей, но у каждого есть несколько методов с одинаковыми именами (A.doSomething, B.doSomething, C.doSomething). Следовательно, имея одинаковую сигнатуру функции, класс D, наследующий от A и использующий метод doSomething (), будет «выглядеть одинаково» для E, наследующего от B или C.

Вот эскиз того, что я хотел бы сделать:

class Base {
    public:
    void myMethod(void) { doSomething(); }
};

class Independent {
    public:
        doSomething();
};

clase Derived : public Base : public Independent {
 (...)
};

int main(void) {
   Derived *derivedObject = new Derived();
   derivedObject->myMethod();
}

В этой задаче объект типа "Независимый" предоставляется библиотекой, которую я не могу изменить. Я хотел бы определить базовый класс, который использует методы, которые будут наследоваться позже. Я не мог найти правильный способ сделать это, используя виртуальное наследование, не вызывая неоднозначной компиляции.

1 Ответ

5 голосов
/ 18 июня 2009

У вас там неприятная ситуация. Одним из решений этой проблемы было бы использование шаблона Curily Recurring Template Pattern для выполнения наследования во время компиляции, например:

template <typename D>
class Base {
    public:
        void myMethod(void) { static_cast<D*>(this)->doSomething(); }
};

class Independent {
    public:
        void doSomething();
};

clase Derived : public Base : public Independent {
    /*...*/
};

int main(void) {
   Derived *derivedObject = new Derived();
   derivedObject->myMethod();
}

В качестве альтернативы, вы можете выбрать промежуточный класс для пересылки на Independent (я предполагаю, что у вас есть много классов, производных от тех же Base и Independent, и вы просто не хотите делать это это для каждого класса).

template <typename D>
class Base {
    private:
        virtual void doSomethingImpl();
    public:
        void myMethod(void) { doSomethingImpl(); }
};

class Independent {
    public:
        void doSomething();
};

class IndependentWrapper : public Base : public Independent {
    private:
        void doSomethingImpl() { Independent::doSomething(); }
};

clase Derived : public IndependentWrapper {
    /*...*/
};

int main(void) {
   Derived *derivedObject = new Derived();
   derivedObject->myMethod();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...