【问题标题】:How to override static method of template class in derived class如何在派生类中覆盖模板类的静态方法
【发布时间】:2016-03-17 07:36:33
【问题描述】:

我在重写基类的静态方法时遇到了一点问题,但整个问题非常复杂且太长(游戏引擎中资源管理的泛化),所以这里有一个简化版本:

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(); }

上面的代码在我的例子中输出“bar”,我希望它输出“baz”。我该怎么办?似乎无论我尝试什么,base::foo() 总是调用 base::bar()。我的设计可能有问题。我从来没有遇到过这个问题 - 我该如何解决?

【问题讨论】:

标签: c++ inheritance static


【解决方案1】:

简单的类继承无法实现您想要做的事情;一个方法不能同时是staticvirtual

您需要一个static 方法才能在没有对象(实例)的情况下调用函数;并且您需要将bar 设为virtual,以便bar&lt;int&gt;::foo() 在从derived 实例 调用时调用derived::bar()

这两个特征是相互排斥的。但Curiously Recursive Template Pattern (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();
}

Live example

【讨论】:

  • 非常感谢!你的回答对我有帮助!
  • 这个答案让我大吃一惊。编译器如何知道类 T 上会有一个 bar() 方法?它是否静态检查 base 的每个实例以确保它适合使用情况?
  • @MayaNedeljkovich 它没有。任何时候对base&lt;T&gt;::foo 进行特化(在示例程序中,调用base&lt;derived&gt;::foo 的确切时间),它确实检查base&lt;T&gt;::foo 是否对给定的T 有意义。这就是所谓的模板第二遍编译(又名“in deduced context”)。如果不是这样,=> 编译错误。 Try it by yourself.
  • @YSC:+1 两次提供现场示例!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 2018-06-06
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多