Chinaunix首页 | 论坛 | 博客
  • 博客访问: 339032
  • 博文数量: 88
  • 博客积分: 1695
  • 博客等级: 上尉
  • 技术积分: 1380
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-06 15:48
个人简介

喜欢美食, 旅行..

文章分类

全部博文(88)

文章存档

2014年(2)

2013年(12)

2012年(14)

2010年(8)

2009年(52)

我的朋友

分类: C/C++

2013-02-06 11:23:42

关于这个话题,在网上看一个哥们的博客写得挺清楚的,这里原文转载

=============================================

     我们先来看一个简单的例子: 

     template   
     class CuriousBase {  
         …  
     }; 

     class Curious : public CuriousBase {  
         …  
     };//摘自<> 
       //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< 
     { 
  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 << "number of MyString: "  
               << MyString::live() << std::endl;  
     std::cout << "number of MyString: "  
               << ws.live() << std::endl;  
 }  

阅读(2046) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~