2013-12-11 5 views
-1

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

class Base { 
public: 
    virtual void foo(int) const {...} 
} 

template <class T> 
class TmplClass : public Base { 
public: 
    virtual void foo(int i) const { foo(T(i)); } 
    virtual void foo(T& param) const { 
     printf("Template::Foo\n"); 
     bar(param); 
    } 
    virtual void bar(T&) const { 
     printf("Template::Bar\n"); 
    } 
} 

class Derived : public TmplClass<SomeConcreteType> { 
public: 
    void bar(SomeConcreteType&) { 
     printf("Derived::Bar\n"); 
    } 
} 

int main() { 
    Derived d; 
    Base* b = &d; 
    b->foo(1); 
} 

Об исполнении я получаю:

Template::Foo 
Template::Bar 

Почему не во время выполнения отправки на вызов, чтобы запретить работу? Если я перегружаю foo в Derived, то он вызывает производную версию foo, почему она не может выполнять динамическую отправку для бара?

Поскольку я работаю в существующем коде, я бы предпочел не менять базовую структуру классов здесь. Я надеюсь найти способ заставить работать вызов или понять, почему это не так. Я пробовал много разных вещей, основываясь на чтении других вопросов здесь, но все это безуспешно.

+0

Где '' Base' в родословной Derived' в? –

+0

Это не похоже на рабочий пример. 'void foo (void)' метод не существует, 'Base' не является классом предков. Предоставьте рабочий код. – Jack

+0

Это не работает, потому что этот код не компилируется. [Эта аналогичная программа] (http://coliru.stacked-crooked.com/a/f97076ef0ad89f1f) компилируется и работает нормально. – Casey

ответ

1

Оказывается, это не проблема с шаблоном. Проблема с кодом заключается в том, что метод Derived :: bar не помечен как const, где, поскольку метод TmplClass :: bar отмечен как const. Таким образом, намерение состояло в том, чтобы обеспечить чрезмерную езду, но на самом деле Derived :: bar - это совершенно другой метод с другой подписью, поэтому именно это привело к непредвиденному поведению. После того, как сопы удаляются из TmplClass :: бара или добавляются к Derived :: бара затем матчу подписей и ожидаемому результату получено:

Template::Foo 
Derived::Bar