The Curiously Recurring Template Pattern (转)

The Curiously Recurring Template Pattern (转)[@more@]  看到这个题目你可能会觉得奇怪,CRTP是什么呢?CRTP是The Curiously Recurring Template Pattern的缩写.

 我们先来看一个简单的例子:
 template  
 class Curio usbase { 
 … 
 }; 

 class Curious : public CuriousBase { 
 … 
 };//摘自<ide>>
 //16.3 The Curiously Recurring Template Pattern (CRTP)

 如果是第一次看到,你可能会觉得奇怪(我也想了半天),这里不会形成递归吗?这里有两个地方可能会产生递归,首先是声明,其次是实现的时候.比如说下面的代码:
 template  
 class CuriousBase 
 {
  public:
  CuriousBase()
  {
  new Derived;
  }
 }; 

 class Curious : public CuriousBase 
 { 
  public:
  Curious()
  {
  }
 };
 
 如果你的 程序中加入了这样的代码,恭喜你了,你中了我们的大奖--崩溃;

 你可能会问,即使我们能避免这样的递归,可是这样的结构有什么用呢?

 我们先假设有种情况,比如说你的项目里面可能有10000多个类,现在要求你每个类都要实现print() 函数,负责将类型的大小输出到std::cout上面,你们的老板还发话了,用函数实现,因为将来这个操作可能需要变更,最可气的是他规定说最好是不要用全局函数.

 第一个念头是继承一个有函数print()的接口
 class IAblePrint
 {
 public:
  void print()
  {
  cout<  }
 };
 可惜这样做的结果不是我们需要的,那么我们设这个函数成为虚函数,然后每个类实现自己的?老天,那里有10000多个类等着我们呢.虽然全局函数是个不错的解决方案,但是那个可恶的老板!

 直觉告诉我们,这些成员函数一定是要实现的,可是有没有办法让 编译器来替我们完成这些无聊的工作呢?

 下面就该CRTP登场了
 template
 class AblePrintSize
 {
 public:
  void print()
  {
  cout<  }
 };

 class Test1:public AblePrintSize
 {
  int t;
 };

 class Test2:public AblePrintSize
 {
  int t[2];
 };

 int main() 
 {
 Test1 hu1;
 Test2 hu2;

 hu1.print();
 hu2.print();
 }

 这里我们只是自己多写了一个template class就达到了我们的目标.上面的例子可能举的不是很好,下面有个比较好的例子(摘自<>
),大家可以参考参考

#include  

template  
class  objectCounter { 
 private: 
 static size_t count; // number of existing objects 

 protected: 
 // default constructor 
 ObjectCounter() { 
 ++ObjectCounter::count; 
 } 

 // copy constructor 
 ObjectCounter (ObjectCounter const&) { 
 ++ObjectCounter::count; 
 } 

 // destructor 
 ~ObjectCounter() { 
 --ObjectCounter::count; 
 } 

 public: 
 // return number of existing objects: 
 static size_t live() { 
 return ObjectCounter::count; 
 } 
}; 

// initialize counter with zero 
template  
size_t ObjectCounter::count = 0; 

/*If we want to count the number of live (that is, not yet destroyed) objects for a certain class type, it suffices to derive the class from the ObjectCounter template. For example, we can define and use a counted string class along the following lines:*/

// inherit/testcounter.cpp 

#include "objectcounter.hpp" 
#include  

template  
class MyString : public ObjectCounter > { 
 … 
}; 

int main() 

 MyString s1, s2; 
 MyString ws; 
 std::cout <: " 
 <::live() < std::cout <: " 
 <} 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-963612/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-963612/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值