奇特递归模板模式

 有些时候需要对一个类新添加的对象进行计数,这个估计很多人都会,所有工作就是添加静态成员、修改构造函数和析构函数而已。但有时候又会有一些麻烦的事发生,就是想对一个类家族的每一个类都进行单独计数时,难道每个类单独添加这样的工作么,这样的工作量也未免太大了吧?但是采用从基类继承下来的方法又会有另一个问题出现,下面看看代码:

01 //: C05:CountedClass2.cpp
02 // Erroneous attempt to count objects.
03 #include <iostream>
04 using namespace std;
05 class Counted {
06 static int count;
07 public:
08 Counted() { ++count; }
09 Counted(const Counted&) { ++count; }
10 ~Counted() { --count; }
11 static int getCount() { return count; }
12 };
13 int Counted::count = 0;
14 class CountedClass : public Counted {};
15 class CountedClass2 : public Counted {};
16 int main() {
17 CountedClass a;
18 cout << CountedClass::getCount() << endl;    // 1
19 CountedClass b;
20 cout << CountedClass::getCount() << endl;    // 2
21 CountedClass2 c;
22 cout << CountedClass2::getCount() << endl;   // 3 (Error)
23 } ///:~

这种情况下是为派生自Counted所有类进行计数,而不是我们要的对每个派生自Counted单独进行计数,因为派生自Counted的所有类都共享了相同且唯一的静态数据成员。这时要怎么办,难道要自己为每个类都进行重复的工作么?其实一种奇特的模板构造实现了这种方式,如下:

 
01  //: C05:CountedClass3.cpp
02  #include <iostream>
03  using   namespace   std ;
04  template < class   T >   class   Counted   {
05  static   int   count ;
06  public :
07  Counted ()   {   ++ count ;   }
08  Counted ( const   Counted < T >& )   {   ++ count ;   }
09  ~ Counted ()   {   -- count ;   }
10  static   int   getCount ()   {   return   count ;   }
11  };
12  template < class   T >   int   Counted < T >:: count   =   0 ;
13  // Curious class definitions
14  class   CountedClass   :   public   Counted < CountedClass >   {};
15  class   CountedClass2   :   public   Counted < CountedClass2 >   {};
16  int   main ()   {
17  CountedClass   a ;
18  cout   <<   CountedClass :: getCount ()   <<   endl ;      // 1
19  CountedClass   b ;
20  cout   <<   CountedClass :: getCount ()   <<   endl ;      // 2
21  CountedClass2   c ;
22  cout   <<   CountedClass2 :: getCount ()   <<   endl ;     // 1 (!)
23 
24  }   ///:~
 
这样的话每个类都派生于一个唯一的基类,这个基类将它本身(派生类)作为模板参数!它看起来似乎是很奇怪的用法,好像陷入了一个递归的定义。其实由于Counted的数据成员不依赖于类型T,当模板被解析的时候,Counted的大小就可以知道了(这个可以试下用不同的类型参数来实例化Counted,会发现Counted的大小总是相同的)。因此实际上用什么样的参数来实例化Countd无关紧要,因为它的大小总是相同的。当它被解析时,用任意一个Counted实例的派生类当然也就可以了。现在因为每个类都派生自唯一的基类,所以都有属于自己的静态数据,这样就可以对每个派生类进行单独的计数了,而避免了重复的添加工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值