2015-07-03 1 views
2

Рассмотрим следующий фрагмент кода:Мульти наследование с интерфейсом шаблона

template.h

template<typename T> 
class templ{ 
public: 
    virtual const int virtualMethod(const T *const) const = 0; 
} 

Base.h

#include "template.h" 

class Der1; 
class Der2; 

    class Base : 
     public templ<Base>, 
     public templ<Der1>, 
     public templ<Der2>{ 
    public: 
     virtual ~Base(){} 
    }; 

Der1.h

#include "Base.h" 

class Der1 : public Base { 
public: 
    virtual const int virtualMethod(const Base *const) const override; 
    virtual const int virtualMethod(const Der1 *const) const override; 
    virtual const int virtualMethod(const Der2 *const) const override; 
}; 

Der1. cpp

#include "Der1.h" 

const int Der1::virtualMethod(const Base *const sth) const{ 
    return sth->templ<Der1>::virtualMethod(this);//does not work 
    //how to fix it? 
} 

const int Der1::virtualMethod(const Der1 *const sth) const{ 
    //do sth 
} 

const int Der1::virtualMethod(const Der2 *const sth) const{ 
    //do sth 
} 

Класс Der2 также наследует базу и реализует эти три функции.

Для этого кода компилятор дает мне эти сообщения:

  1. 'Темпл' неоднозначное "Кандидаты: Templ() Templ() Templ (Const Templ &) Templ Templ (Const Templ &)() Templ (Const Templ &) '
  2. функция „virtualMethod“ не может быть решена
  3. функция члена пространства имен „virtualMethod“ не может быть решена.
  4. Тип «Der1» не может быть разрешен.
  5. неопределенная ссылка на ` Templ :: virtualMethod (Der1 сопзЬ *) сопзЬ»

В общем, идея кодекса было реализовать двойной тип отправки. Хотя я думаю, что знаю, что вызывает проблемы, я понятия не имею, как его решить. Так что, может быть, ты поможешь мне.

+0

Вы, вероятно, хотите использовать [CRTP] (https://en.wikipedia.org/ wiki/Curiously_recurring_template_pattern), а не встроенный абстрактный базовый класс. –

+0

Пожалуйста, не смешивайте статический полиморфизм (шаблоны) и динамический полиморфизм (виртуальный), если вы не знаете, что делаете. –

+0

Кроме того, при определении интерфейсов вы должны использовать виртуальное наследование (избегать нескольких базовых классов) –

ответ

0

Я немного запутался, что было ваше намерение ...

Но что:

const int Der1::virtualMethod(const Base *sth) const { 
    return dynamic_cast<const templ<Der1> *>(sth)->virtualMethod(this); 
} 
+0

Это, безусловно, ** НЕ **, что я искал. Основная цель написанного мной кода - избегать dynamic_cast и RTTI. Не стоит забывать, что ваш код опасен из-за того, что не проверен динамический результат репликации для 'nullptr'. – bartop

+0

Конечно, вы должны проверить результат литья, но я игнорирую это, потому что это не большинство решений, и я думаю, что в этой ситуации это не требуется, потому что приведение всегда будет положительным (если sth = nullptr, он не проверяется в вашем код тоже). – yzz