zoukankan      html  css  js  c++  java
  • 奇异模板递归模式

    CRTP

    概念

    Curiously Recurring Template Pattern,奇异模板递归模式,即基类为类模板,把派生类作为基类的模板参数,基类中的成员函数可以(通过 static_cast 转换为派生类类型)访问派生类的成员函数。

    原理

    这称作编译期(静态)多态,其原理是利用了基类(类模板)的实例化(为一个独立的类)发生于派生类声明之后,即在派生类声明后才可能调用基类(类模板)中的方法进而进行实例化

    功能及使用示例

    普通静态多态调用

    即通过基类(类模板)实例的引用或指针调用基类中某方法后,又间接调用了派生类中的实现,模似出多态的效果,代码示例

    链式静态多态调用

    即调用某方法后返回当前实例的引用,支持形如 inst.Func1().Func2().Func3() 的调用。在有发生继承情况时,基类方法需要返回派生类实例的引用,代码示例

    为派生类添加接口

    继承自计数器类模板

    统计创建过的某类的实例个数,可以通过在类中声明/定义一个静态成员变量实现,但这一功能并不需要在需要统计其创建实例个数的类中重复实现。

    比如可以设计一个独立的计数器类,其它类以组合的方式,将计数器类作为本类的一个静态成员变量,也可以实现统计功能。另一种方法是继承计数器类模板,每个派生类所继承的基类(类模板)实例都是独一无二的,因此统计每个派生类的实例个数是互不影响的,代码示例

    拷贝自身

    面向对象编程中,如果需要添加(动态)多态接口,通常需要在基类中添加虚函数,同时也需要在所有派生类中添加相应的虚函数。考虑返回一个自身的拷贝的功能,在所有派生类中添加相应的虚函数处理会造成代码重复,这种情况下可以考虑在抽象基类中声明虚函数,CRTP派生类中相应虚函数实现会拷贝出一个派生自它的派生类的实例,即结合了动态多态与静态多态,代码示例

    Expression Templates

    表达式模板,待了解补充

    注意事项

    避免实际派生类与传递给基类(类模板)的模板参数不同

    声明实际派生类时,传递给基类(类模板)的模板参数与实际派生类不同可能会通过编译,但也可能会造成隐避的bug或未定义错误。通过将基类(类模板)的构造函数声明为私有 + 声明派生类为基类友元,限制只有实际派生类可调用实例化的基类(类模板)类型的构造函数,从而触发编译错误。代码示例

    基类(类模板)实例化

    注意每个实例化出来的类模板类型都是不同的,可参考上述『计数器类模板』使用

    统一存储派生类

    由于每个实例化出来的类模板类型都不同,只有继承于某个抽象基类的CRTP派生类才能统一存储,其形式为存储抽象类型,如 std::vector<Abstract*>,可参考上述『拷贝自身』功能

    参考

    奇异递归模板模式(Curiously Recurring Template Pattern,CRTP)1
    Curiously recurring template pattern wiki

  • 相关阅读:
    移位乘除法
    标准C++的一些约定
    图论的一些定义
    二进制取数在多重背包和母函数中的应用
    深入理解最小割的意义
    pku 3020 最小路径覆盖集
    pku 1986 LCA算法的应用
    pku 1185
    连通分量(tarjan算法)
    pku 2983 差分约束系统判断
  • 原文地址:https://www.cnblogs.com/wangzhiyi/p/13308503.html
Copyright © 2011-2022 走看看