C ++中的静态多态性

时间:2014-08-28 22:46:46

标签: c++ polymorphism

#include <iostream>

template<typename Impl>
struct renderer{
    void get(){
        static_cast<Impl*>(this)->get();
    }
};
struct open_gl : public renderer<open_gl>{
    void get(){
        std::cout << "OpenGL" << std::endl;
    }
};
struct direct_draw : public renderer<direct_draw>{
    void get(){
        std::cout << "DX" << std::endl;
    }
};
template<typename T>
void print_renderer(renderer<T> r){
    r.get();
}
int main() {
    auto gl = open_gl();
    auto dx = direct_draw();
    print_renderer(gl);
    print_renderer(dx);
}
  1. 为什么我不能将print_renderer的参数更改为void print_renderer(const renderer<T> &r)cannot convert 'this' pointer from 'const renderer<open_gl>' to 'renderer<open_gl> &' `

  2. 当我在open_gl中重命名方法get时,为什么会出现运行时错误 得到get1?这不会触发编译器错误吗? Error = Stack overflow

  3. **注意我使用的是最新的MSVC

2 个答案:

答案 0 :(得分:12)

1)因为get不是const成员函数:它不能承诺不修改你的(const)参数。

您可以将get声明为const,并且编译正常:

void get() const { ... }

2)将调用基本get方法,进入无限递归:Stack Overflow。

如果你声明你的函数override(它需要是虚拟的),如果编译器确实没有覆盖基本方法,它将抛出一个错误:

void get1() override  { ... } // Compiler error
void get() override   { ... } // Ok

注意:

标题是“C ++中的静态多态”,但我认为你误解了什么是静态多态:它不(必须)利用继承(就像你一样)。相反,模板编译时鸭子类型将为您静态“解析”函数调用。

也就是说,您不需要相关类型,根本不需要基类renderer类,您只需执行以下操作(在这种情况下,重命名为get1 < em>将导致编译器错误):

#include <iostream>

struct open_gl {
    void get(){
        std::cout << "OpenGL" << std::endl;
    }
};
struct direct_draw {
    void get(){
        std::cout << "DX" << std::endl;
    }
};

template<typename T>
void print_renderer(T r){
    r.get();
}

int main() {
    auto gl = open_gl();
    auto dx = direct_draw();
    print_renderer(gl);
    print_renderer(dx);
}

<强> Live demo

答案 1 :(得分:5)

  1. 由于get未标记为const
  2. 因为使用了基类方法(与强制转换无关),它进入无限循环。