奇异递归模板

奇异递归模板

CRTP通过将基类模板设置为子类,从而实现静态多态(编译器多态),或者扩展接口(委托实现)
要点解析:
1:class Sub : public Base<Sub>,通过模板参数,将子类信息注入到基类,从而实现基类中提前获取子类类型信息
2:static_cast<T*>(this),将基类指针转为模板子类T的指针
3:Base类型是不完整类,不能直接用Sub参与内存布局,但可以在类接口中使用(实际发生调用的时候,模板在编译的时候就辨析了)
4:删除对象,也要使用编译时多态进行删除,避免直接delete
5:模板CRTP基类不能有virtual(因为要编译时多态)

一般用在性能要求非常苛刻的环境中,评测预估性能提升30~40%。 对于一般开发,使用多态更方便阅读。

代码实现

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <vector>
using namespace std;

// 基类参数T包含了子类编译时信息
template <typename T> //T一定要子类才能crtp,子类信息注入到父类
class Base {
public:
    void process() { 
      sub()->process_imp(); //编译时分发
    }

    //如果不实现,类似纯虚函数
    void process_imp() { 
      cout<<"Base::process()"<<endl;
    }

    //将基类指针转型为子类T的指针,static_cast编译多态,dynamic_cast要求虚函数
    T* sub() { return static_cast<T*>(this); }	//this就是main中的ps1,转型为子类

    ~Base()	//也可以改为virtual,也会析构正常,但会产生虚函数表,背离了编译时多态
    {
      //delete sub(); // static_cast<T*>(this);	//会死循环,子类调用父类,父类又要调用子类
      cout<<"~Base()"<<endl;	//必须先析构子类,再析构父类
    }

    void destroy() 
    { 
        delete sub();// static_cast<T*>(this); 
    }

//	T b; //不能,T还是不完整类型,不能参与内存布局
//只能用指针,因为语义上,Base中包含一个sub,而sub又继承base,会导致死循环
};

class Sub1 : public Base<Sub1> {
public:
    ~Sub1()
    {
      cout<<"~Sub1"<<endl;
    }

    void process_imp() { 
      cout<<"Sub1::process()"<<endl;
    }
};

template <typename T>
void invoke(Base<T>* pb)
{
  pb->process();
}

int main()
{
  Base<Sub1> *ps1=new Sub1();	//声明基类,效果类似虚函数,只是为编译时多态
  ps1->process();// process(ps1)

  invoke(ps1);
  //delete ps1;	//不能正确删除,因为是编译时删除,只是删除了基类
  ps1->destroy();
}

代码执行

kongcb@tcu-pc:~/testcode/template$ g++ crtp_interface.cpp -o crtp_interface
kongcb@tcu-pc:~/testcode/template$ ./crtp_interface
Sub1::process()
Sub1::process()
~Sub1
~Base()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术的微光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值