C++中的静态多态性

Static polymorphism in C++

本文关键字:多态性 静态 C++      更新时间:2023-10-16
#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. 为什么当我重命名方法时出现运行时错误 get open_gl得到1?这不应该触发编译器错误吗? Error = Stack overflow

**注意我正在使用最新的 MSVC

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

你可以将get声明为 const ,并且编译良好:

void get() const { ... }

2(将调用基本get方法,进入无限递归:堆栈溢出。

如果你声明你的函数override(它必须是虚拟的(,如果编译器没有真正覆盖基方法,它将抛出错误:

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

注意:

标题是"C++中的静态多态性",但我认为您误解了什么是静态多态性:它没有(必须(利用继承(就像您所做的那样(。相反,模板编译时鸭子类型将静态地"解析"函数调用。

也就是说,你不需要

相关类型,你根本不需要基renderer类,你可以简单地执行以下操作(在这种情况下,重命名为get1将导致编译器错误(:

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

现场演示

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