利用C++模板复用静态类对象

     在《C++高效编程》中有一篇文章叫做Counting Objects。主要讲述了利用模板复用静态类对象,看完觉得不错,小记一下。

一   问题
     如果想要做一个统计子类实例个数的代码,比方说统计控件Widget的个数,我们会怎样写?

二   一般解法
class Counter
     {
public:
Counter(){++count;}
Counter(const Counter&){++count;}
~Counter(){--Count;}

static size_t Number();
private:
size_t count;
};

    size_t Counter::count = 0;

    class Widget:public Counter
{
};

三 存在的问题
   1.如果我想要统计一个其他类别子类的个数,Counter还能复用吗?
   2.这个能阻止客户端代码调用Counter* iCount = new Widgets吗?如果调用了,delete iCount可是会造成内存泄露的。为了防止这种内存情况,Counter的析构函数必须为虚函数,这样会增加对象的空间。

四 解决方案
    1.Counter对象复用
如果是上述写法,继承Counter就等于同时继承了其静态变量,会导致两种不同的统计对象相加到一起,只能再写一个和Counter一模一样的类,只不过名字不同了。但是可以运用模板解决问题,其实模板就是在编译时根据类型实例化一个特别的类。因此,Counter这样写就可以复用了.
      template<typename T>
      class Counter
      {
public:
......(以上内部代码一样)
      };
     template<typename T> Counter<T>::count = 0;
     class Widget:public Counter<Widget>
     {
     };
     class OtherObject:public Counter<OtherObject>
     {
     };
   2.阻止客户端新建子类对象赋值到父类指针
      方法一: 内部私有化Counter的delete操作符,编译器编译提示删除对象不可访问,从而达到保护的目的。这种方法感觉很恶心,提示错误的地方不在new而在delete,所以不推荐.
      方法二: 私有继承Counter类,只是公布需要使用的Counter类的接口;
      class Widget:private Counter<Widget>
      {
public:
using Counter<Widget>::Number;
      };
Counter<Widget>* iCount = new Widget;  
    //此句编译会提示出错,error: `Counter<Widget>' is an inaccessible base of   `Widget'
    但是Number方法仍然可以照常使用;

利用模板实现对象复用,是C++常用的技术,也是模板的优势所在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值