c++ - 这是静态多态性的 CRTP 用法,但没有实现派生函数。在 gcc 和 visual studio 中编译。为什么?

标签 c++ polymorphism crtp

#include <iostream>

template <class Derived>
class Base
{
public:
  void method1()
  {
    static_cast<Derived*>(this)->method1();
  }

  void method2()
  {
    static_cast<Derived*>(this)->method2();
  }
};

class Derived1: public Base<Derived1>
{
public:
  void method1()
  {
    std::cout << "Method 1 of Derived1 executed.\n";
  }
};

int main(int argc, char *argv[])
{
  Derived1 d1;
  d1.method1();
  d1.method2();
  return 0;
}

跟进问题:如何使这种类型安全?也就是说,如果有人忘记实现 method2,我希望编译器能够捕捉到它。我不希望它在运行时爆炸。

最佳答案

我认为这是有效的原因是如果你实例化这段代码:

void method2()
{
  static_cast<Derived*>(this)->method2();
}

其中 Derived 没有 method2() 的实现,本质上是一个美化的自递归调用。这里的原因是,在Derived1中,确实有一个名为method2的成员函数,即继承自基类的成员函数。

我尝试运行这段代码,果然对 method2 的调用导致自递归堆栈溢出。

通常,CRTP 通过不让基类函数调用同名的派生类函数来避免这种情况。这样,如果派生类缺少特定函数,调用会触发编译器错误。在您的情况下,这不会发生,因为可以从基类间接引用函数本身。

关于c++ - 这是静态多态性的 CRTP 用法,但没有实现派生函数。在 gcc 和 visual studio 中编译。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4721047/

相关文章:

c++ - CRTP - 从基类检查派生类是否满足要求

c++ - 参数前的 "class"是什么意思?

c++ - 为什么 MessageBox 会默默地失败?

c++ - 避免在 ListView 中截断标签

c++ - 我如何使用位操作对单个整数中的两个数字进行编码和解码?

xml - 解码混合对象类型的 xml 数组

c++ - 为什么 CRTP 实现和接口(interface)方法的命名不同?

ruby-on-rails - 在 Rails 和多态关系中使用 UUID 作为主键

functional-programming - 如何与 Elm 中的多态子组件通信?

c++ - CRTP - 嵌套叶类类型的可见性