C++编程模式CRTP

2016-12-30 09:53:50来源:oschina作者:lieefu人点击

第七城市

CRTP ,curiously recurring template pattern 神奇的复发模板范式,recurring实在不好翻译,没有合适的词汇,意思是继承的父类是个模板类,参数是自己。上代码看一下吧:


// The Curiously Recurring Template Pattern (CRTP)
template
class Base
{
// methods within Base can use template to access members of Derived
};
class Derived : public Base
{
// ...
};

目的是啥呢?主要解决的是虚函数实现的多态效率低下的问题,继承层次多了,虚函数这种动态实现多态的机制效率低下,资源浪费严重。


CRTP用法一,实现静态多态(Static polymorphism),上代码:


template
struct base
{
void interface()
{
// ...
static_cast(this)->implementation();
// ...
}
};
struct derived : base
{
void implementation()
{
// ...
}
};

模板带来的好处是,只有Base::implementation()使用时,静态函数才实例出来。这种用法有时被称为"simulated dynamic binding",模拟的动态绑定。


传统的多态是这样的,使用基类指针指向实例化后的子类,通过虚函数实现多态。


class Base
{
public:
virtual void method() { std::cout << "Base"; }
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual void method() { std::cout << "Derived"; }
};
int main()
{
Base *pBase = new Derived;
pBase->method(); //outputs "Derived"
delete pBase;
return 0;
}

CRTP用法二,对象计数(Object counter),记录一个类被创建和销毁的次数,上代码:


template
struct counter
{
static int objects_created;
static int objects_alive;
counter()
{
++objects_created;
++objects_alive;
}counter(const counter&)
{
++objects_created;
++objects_alive;
}
protected:
~counter() // objects should never be removed through pointers of this type
{
--objects_alive;
}
};
template int counter::objects_created( 0 );
template int counter::objects_alive( 0 );
class X : counter
{
// ...
};
class Y : counter
{
// ...
};

能够对X和Y类分开计数,只能用模板实现,普通的继承基类无法实现。


CRTP用法三,多态拷贝构造(Polymorphic copy construction)上代码:


// Base class has a pure virtual function for cloning
class Shape {
public:
virtual ~Shape() {};
virtual Shape *clone() const = 0;
};
// This CRTP class implements clone() for Derived
template
class Shape_CRTP : public Shape {
public:
virtual Shape *clone() const {
return new Derived(static_cast(*this));
}
};
// Nice macro which ensures correct CRTP usage
#define Derive_Shape_CRTP(Type) class Type: public Shape_CRTP
// Every derived class inherits from Shape_CRTP instead of Shape
Derive_Shape_CRTP(Square) {};
Derive_Shape_CRTP(Circle) {};

传统的实现方式是,基类有个虚拟clone函数,每个继承类实现自己的clone函数功能。依靠CRTP技术,只定义一个就够了,大家通用。


资料来源:https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台