多态是指同一个方法在基类和不同派生类之间有不同的实现,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(){}
				
stl_interfaces Boost.Iterator的iterator_facade和iterator_adaptor部分(现在称为iterator_interface )的更新的C ++ 20友好版本; C ++ 20的view_interface的C ++ 20之前版本; 还有一个名为container_interface的新模板,用于帮助创建新容器; 所有定位标准化。 该库至少需要C ++ 14。 对于迭代器部分-如果您需要编写迭代器,则iterator_interface会将其设置为: struct repeated_chars_iterator using value_type = char ; using difference_type = std:: ptrdiff_t ; using pointe
这里将基类转换成派生类用的是static_cast静态绑定,而普通基类转派生类用的是dynamic_cast动态绑定。 动态绑定的目的是为了确保你所转化的派生类是正确的,而对于CRTP来说,基类是继承于模板类的参数,也就是派生类本身。 这也正是CRTP这种设计的目的。 2.CRTP的优点 多态是个很好的特性,但是动态绑定比较慢,因为要查虚函数表。eg: 2.轻松地实现各个子类实例创建和析构独立的计数 3.多态链(Polymorphic 了解过后,发现是一个Java泛型Trick1,并且在C++中也有术语CRTP2,简单的记录一下。 Java:泛型Trick 在唯一能找到的例子当中,该写的好处是:允许我们能够在基类/接口中定义具体子类相关的方。 在一般的Interf
1. 什么是CRTP? 什么是CRTP?CRTP的全称是Curiously Recurring Template Pattern,即奇异递归模板模式,简称CRTP。CRTP是一种特殊的模板技术和使用方式,是C++模板编程中的一种惯用。CRTP的特性表现为: 基类是一个模板类 派生类继承该基类时,将派生类自身作为模板参数传递给基类 典型代码如下: // 基类是模板类 template <typename T> class Base public: virtual ...
装逼一点的名字叫做:奇异递归模板模式 在平常开发设计类的过程中,我们常常会将两个类通用的部分抽出来,上移至一个父类,存在差异的部分在父类中定义为虚函数,在子类具体实现。 最近开发过程中,遇到一个这样的问题: 有这么一个类A: 类A里有一系列函数,是基于通过某种索引idx1获取一个值实现的 (即:这一系列函数都会调用一个叫做GetAttr(idx1) 的函数) 现有另一种索引id
虚函数是C++实现多态的工具,在运行时根据虚表决定调用合适的函数。这被称作动态分发。虚函数很好的实现了多态的要求,但是在运行时引入了一些开销,包括: 对每一个虚函数的调用都需要额外的指针寻址 虚函数通常不能被inline,当虚函数都是小函数时会有比较大的性能损失 每个对象都需要有一个额外的指针指向虚表 所以如果是一个对性能要求非常严格的场合,我们就需要用别的方式来实现分发,这就是今天这篇博客的主角CRTP。 CRTP通过模板实现了静态分发,会带来很多性能的好处。可以参见The cost of dyn
C++RAII惯用C++资源管理的利器   RAII是指C++中一种惯用(idiom),它是《Resource Acquisition Initialization》的首字母缩写。中文可将其翻译为“资源获取就是初始化”。虽然从某种程度上说这个名称并没有体现出该惯性的本质精神,但是作为标准C++资源管理中的关键技术,RAII早已在C++社群中深入人心。   RAII惯用在Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)的《C++程序设计语言》一书中有提及。当讲述C++资源管理时,Bjar