web-dev-qa-db-ja.com

派生クラスのテンプレートクラスの静的メソッドをオーバーライドする方法

基本クラスの静的メソッドのオーバーライドに少し問題がありますが、質問全体が非常に複雑で長すぎます(ゲームエンジンのリソース管理の一般化)。

template<class T>
class base
{
    static void bar()
    { printf("bar"); }
public:
    static void foo()
    { bar(); }
};

class derived : public base<int>
{
    static void bar()
    { printf("baz"); }
};

int main() { derived::foo(); }

上記のコードは「バー」を出力しますが、「baz」を出力したいと思っています。どうすればいいですか?私が何を試みても、base :: foo()は常にbase :: bar()を呼び出すようです。デザインに問題があるかもしれません。私はこの問題に遭遇したことがありません-どうすれば解決できますか?

15
Biser Krustev

あなたがやろうとしていることは、単純なクラス継承では達成できません。メソッドをstaticvirtualの両方にすることはできません。

オブジェクトなしで関数を呼び出すには、staticメソッドが必要です(インスタンス)。 barvirtualである必要があります。これにより、derivedから呼び出されたときにbar<int>::foo()derived::bar()を呼び出すようになりますインスタンス

これら2つの特性は相互に排他的です。しかし、不思議な再帰的なテンプレートパターン(CRTP)がここでの解決策になる場合があります。

#include <iostream>

template<class T>
struct base
{
    static void foo()
    {
        T::bar();
    }
};

struct derived : public base<derived>
{
    static void bar()
    {
        std::cout << "derived" << std::endl;
    }
};

int main()
{
    derived::foo();
}

実例

25
YSC