C++ 惯用法之 CRTP

2023-11-19

背景

CRTP 是 一种 C++ 的设计方法,其巧妙的结合了继承和模板编程技术,可以用来给类提供额外的功能。

CRTP

①.概述

CRTP 的基本特征表现为:基类是一个模板类;派生类在继承该基类时,将派生类自身作为模板参数传递给基类。

②.实现示例

template<typename T>
class baseDemo
{
public:
    virtual ~baseDemo(){}
    void interface()
{
        static_cast<T*>(this)->imp();
    }
};

class derivedDemo:public baseDemo<derivedDemo>
{
public:
    void imp()
{
        cout << " hello world " << endl;
    }
};

静态多态

①.概述

多态是指同一个方法在基类和不同派生类之间有不同的实现,C++ 通过虚函数实现多态,但是虚函数会影响类的内存布局,并且虚函数的调用会增加运行时的开销。

②.静态多态

CRTP 可以实现静态多态,但本质上 CRTP 中的多个派生类并不是同一个基类,因此严格意义上不能叫多态。

template<typename T>
class baseDemo
{
public:
    virtual ~baseDemo(){}
    void interface() { static_cast<T*>(this)->imp(); }
    void imp() { cout << "imp hello world " << endl; }
};

class derivedDemo1:public baseDemo<derivedDemo1>
{
public:
    void imp(){ cout << "derivedDemo1 hello world " << endl; }
};

class derivedDemo2 :public baseDemo<derivedDemo2>
{
public:
    void imp() { cout << "derivedDemo2 hello world " << endl; }
};

template<typename T>
void funcDemo(T & base)
{
    base.interface();
}

int main()
{
    derivedDemo1 d1;
    derivedDemo2 d2;

    funcDemo(d1);
    funcDemo(d2);
   
    return 0;
}

在这里插入图片描述

代码复用

①.概述

使用 CRTP 可以把重复性的代码抽象到基类中,减少代码冗余。

②.代码示例

template<typename T>
class baseDemo
{
public:
    virtual ~baseDemo(){}
    void getType() 
{ 
        T& t = static_cast<T&>(*this);
        cout << typeid(t).name() << endl;
    }
  
};

class derivedDemo1:public baseDemo<derivedDemo1>
{
};

class derivedDemo2 :public baseDemo<derivedDemo2>
{
};

int main()
{
    derivedDemo1 d1;
    derivedDemo2 d2;

    d1.getType();
    d2.getType();
    
    return 0;
}

在这里插入图片描述

扩展既有类的功能

①.概述

使用 CRTP 可以在基类中调用派生类的成员函数,从而可以在调用前后扩展新的操作。

②.代码示例

template<typename T>
class baseDemo
{
public:
    virtual ~baseDemo() {}
    void interface()
{
        cout << "hello " << endl;
        static_cast<T*>(this)->imp();
    }
};

class derivedDemo :public baseDemo<derivedDemo>
{
public:
    void imp()
{
        cout << "derivedDemo " << endl;
    }
};

int main()
{
    derivedDemo demo;
    demo.interface();
    
    return 0;
}

在这里插入图片描述

CRTP 应用示例

应用 CRTP 可以把一个类变为单例模式,代码如下:

template<typename T>
class singlePatternTemplate
{
public:
    virtual ~singlePatternTemplate() {}
    singlePatternTemplate(const singlePatternTemplate&) = delete;
    singlePatternTemplate & operator=(const singlePatternTemplate&) = delete;

    static T& getSingleObj()
{
        static T obj;
        return obj;
    }
protected:
    singlePatternTemplate(){}
};

class derivedDemo :public singlePatternTemplate<derivedDemo>
{
    friend singlePatternTemplate<derivedDemo>;
private:
    derivedDemo(){}
};

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 惯用法之 CRTP 的相关文章

随机推荐

  • SpringBoot中通过AOP进行全局事务管理

    SpringBoot中使用AOP进行全局事务管理 不废话 直接上干货 实现步骤如下 第一步 pom文件中添加依赖
  • 软件工程基础复习_7

    第7章软件测试 软件验证是通过检查和提供客观证据表明软件已经满足规定的需求 是确保软件质量和降低软件成本的重要手段 进行软件验证的方式有两种测试和证明 软件测试又可以分为两类 静态测试和动态测试 静态测试又称评审 是对软件进行的一种分析和检
  • 前端搜索JS库 Elasticlunr.js

    有Github账号的小伙伴们 帮忙点赞啦 Star 本人写了一个JS的离线搜索库 支持Field search 采用BM25模型进行Ranking Ranking的算法和Elasticsearch一样的 效果比lunr js有很高提升 希望
  • 期权分仓开户资金是否安全?具体保障措施有哪些?

    网上关于期权分仓系统的真假一直都没有定论 两方人的争论也让很多没有接触过期权分仓系统的人摸不着头脑 那么期权分仓靠谱吗 资金在里面安全吗 下文为大家科普期权分仓开户资金是否安全 具体保障措施有哪些 一 期权分仓开户资金的安全性是一个重要的问
  • 延时任务!redis key失效监听,rabbitmq死信队列实现,线程池,任务调度==>实现超时订单/默认好评/定时考试等

    实现超时订单 超期默认好评等等很多常见需要用到延时任务 大概用几种做法 redis key失效监听 rabbitmq死信队列 调度线程池 定时调度 一 redis key失效监听实现 推荐 注意redis conf 放开 notify ke
  • Python测试框架Pytest的基础入门

    Pytest简介 Pytest is a mature full featured Python testing tool that helps you write better programs The pytest framework
  • 【Ant Design】Form.Item创建自定义表单

    一 概述 Antd是一个非常强大的UI组件库 里面的Form表单组件也基本能满足我们大多数场景 但是也有需要自定义表单的场景 Vue2里我们使用v model 结合子组件的model属性 来实现自定义组件的双向绑定 Vue3里我们使用v m
  • 【Jboss】热部署

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net inforstack article details 47681803
  • 蓝桥杯:斐波那契数列最大公约数

    题目表示的很明确 要用两个算法 斐波那契数列是很经典的dp问题 最大公约数是很经典的辗转相除法 从而我理所应当的就定义一个数组存放斐波那契数列 long long int F 2021 0 F 1 1 F 2 1 for int i 3 i
  • 解决SQL Server占用服务器内存过高问题

    最近发现个问题 数据库服务器内存居高不下 64G的内存 几乎被占用100 结果差点把服务器给拖垮了 第一步 打开SQL Server Management Studio 在连接上右键 属性 第二步 内存选项卡 修改最大服务器内存的大小 如下
  • Android Killer的安装和配置 -安卓逆向的必备神器

    图文并茂 详细的不能再详细了 这你总不能学不会吧 都给我学会 安装包我已经放在了文章末尾 需要可以自取哟 1 下载安卓Android killer 首先 我们先下载打包好的Android killer 解压缩后可以得到一大堆没啥用的 文件
  • 用WinHex软件解析FAT32文件系统

    一 工欲善其事 1 准备工作 将一个U盘格式化为FAT32格式 在U盘内创建几个文件 最好是TXT文档 其中至少有一个是长文件 命名较长 2 补充知识 短文件名表示 长文件名表示 Note 当一个文件名为长文件名时 会由几个长文件名表示法和
  • Linux查看当前目录下各文件所占空间

    要查看当前目录下各文件所占空间 可以使用du命令 磁盘使用情况 配合sort命令来实现 以下是在Linux系统中执行的命令 du sh sort hr 解释一下这个命令 du sh 计算当前目录下每个文件和目录的总大小 并以易读的方式显示
  • 给定一个无重复元素的有序整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 n

    class Solution public List
  • 让dapper支持Oracle

    之前的项目数据使用mssql和mysql ORM使用一个轻量级的dapper 感觉很方便 性能也比EF强 关键是语法灵活 上手容易 用这种框架开发了几个网站 感觉非常好 但新项目要使用oracle 就出问题了 dapper里的关键字 在or
  • 史上最全量化交易资源整理

    有些国外的平台 社区 博客如果连接无法打开 那说明可能需要 科学 上网 国内在线量化平台 BigQuant 你的人工智能量化平台 可以无门槛地使用机器学习 人工智能开发量化策略 基于python 提供策略自动生成器 镭矿 基于量化回测平台
  • PCL 大窗口可视化两个点云

    一 主要参数 viewer gt setFullScreen true 设置点云为全屏显示的2D俯视图 二 代码实现 1 一个大窗口可视化两个点云 include
  • 清除history内容

    history记录是记录在 bash history中的 history c 清除的是当前会话的记录 原来的记录是不会被清除的 可以直接删除 bash history 清空这个文件cat dev null gt bash history
  • c++ - 抽象类 和 多态当中一些问题

    抽象类 纯虚函数 在虚函数的后面写上 0 则这个函数为纯虚函数 class A public virtual void func 0 纯虚函数不需要写函数的定义 他有类似声明一样的结构 抽象类概念 我们把具有纯虚函数的类 叫做抽象类 所谓抽
  • C++ 惯用法之 CRTP

    背景 CRTP 是 一种 C 的设计方法 其巧妙的结合了继承和模板编程技术 可以用来给类提供额外的功能 CRTP 概述 CRTP 的基本特征表现为 基类是一个模板类 派生类在继承该基类时 将派生类自身作为模板参数传递给基类 实现示例 tem