-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

bar の呼び出しで実行時ディスパッチが機能しないのはなぜですか? Derived で foo をオーバーロードすると、派生バージョンの foo が呼び出されますが、bar の動的ディスパッチを実行できないのはなぜですか?

私は既存のコードで作業しているので、ここではクラスの基本構造を変更したくありません。通話を機能させる方法を見つけるか、機能しない理由を理解したいと思っています。ここで他の質問を読むことに基づいて、さまざまなことを試しましたが、すべて役に立ちませんでした。

4

1 に答える 1

1

これはテンプレートの問題ではないことがわかりました。コードの問題は、Derived::bar メソッドが const としてマークされていないのに対し、TmplClass::bar メソッドは const としてマークされていることです。したがって、オーバーライドを提供することを意図していましたが、実際には Derived::bar は別の署名を持つまったく別のメソッドであるため、予期しない動作が発生していました。const が TmplClass::bar から削除されるか、Derived::bar に追加されると、署名が一致し、期待される出力が受信されます。

Template::Foo
Derived::Bar
于 2013-12-11T17:44:21.510 に答える