c++基于引用计数的智能指针实现

引用计数指针(Reference CountedPointer)是为了解决C++必须为使用new申请的指针进行delete操作从而防止内存泄露而提出的。在C++中,new和delete必须成对出现,否则会导致内存泄露或错误。以前在写C++程序的时候,成天提心吊胆,生怕由于这个原因出现什么错误。有时候也在想,有没有一种方法,可以使编写C++程序像编写Java或者C#程序那样安心。

 

当然,遇到这种困扰的人不止我一个,在我之前就有许多前辈思考并尝试解决这个问题。引用计数指针就是其中的一种解决方案。引用计数指针的思想非常简单,就是为类的每个对象都增加一个计数器变量,每当该对象被赋值给一个不同的引用计数指针时时,计数器就会自动加1,当这个引用计数指针被析构的时候,计数器就会自动减1,当计数器减到0时,说明这个对象已经不再被使用,于是将这个对象释放。

 

许多开源的项目中都有用到这种方法。比如,irrlicht游戏引擎和Nebula 3游戏引擎中都能看到这种方法的影子。基于Nebula 3游戏引擎中的代码,我自己重新整理实现了一份代码。文章的最后给出了下载链接。

 

在使用的时候,只需令希望使用引用计数指针的类继承ReferenceCounter类即可,然后用new关键字声明该类的对象指针,并将这个指针赋值给一个RefCountedPointer<>对象。但是,这里有一点需要注意的是,继承了ReferenceCounter的类就不能再多重继承其他实类了,否则将无法正确释放对象的空间。例如,

  
  
1 classCDerivation : public CBase, public ReferenceCounter 2 { 3   ... 4 };

 

如果其中CBase是一个实类,那么,这样的代码是不允许的,Debug的时候,要释放空间的地址并不是CDerivation对象的地址,而是ReferenceCounter对象地址相对于CDerivation对象的地址的偏移地址。为了解决这个问题,可以令基类继承自ReferenceCounter类,其他派生类继承基类的同时也就继承了ReferenceCounter类。例如,

复制代码
  
  
1 classCBase : public ReferenceCounter 2 { 3   ... 4 }; 5 classCDerivation : public CBase 6 { 7   ... 8 }; 9  
复制代码

 

注意,上面所说的是不能多重继承其他实类,如果一个类想使用引用计数指针,并且除了继承ReferenceCounter类以外,继承的其他类都是接口(就是只包含纯虚函数、静态常量和静态常量,且不包含任何其他成员变量或函数的类,这种接口的概念与Java和C#中接口的概念几乎相同),那么,这种多重继承是允许的。例如,

复制代码
  
  
1 #include < iostream > 2   using namespace std; 3 4 #include " RefCountedPointer.h " 5 #include " ReferenceCounter.h " 6 7   struct IInterfaceA 8 { 9 static int IA; 10 virtual void displayA( void ) = 0 ; 11 virtual void displayB( void ) = 0 ; 12 }; 13 14   int IInterfaceA::IA = 100 ; 15 16   struct IInterfaceB 17 { 18 static int IB; 19 virtual void displayC( void ) = 0 ; 20 virtual void displayD( void ) = 0 ; 21 }; 22 23   int IInterfaceB::IB = 102 ; 24 25   class CClass : publicReferenceCounter, public IInterfaceA, public IInterfaceB 26 { 27 public : 28 int a; 29 int b; 30 int c; 31 int d; 32 public : 33 virtual void displayA( void ) 34 { 35 cout << a; 36 } 37 38 virtual void displayB( void ) 39 { 40 cout << b; 41 } 42 43 virtual void displayC( void ) 44 { 45 cout << c; 46 } 47 48 virtual void displayD( void ) 49 { 50 cout << d; 51 } 52 }; 53 54 void main( void ) 55 { 56 RefCountedPointer < CClass > p = new CClass; 57 p -> a = 0 ; 58 p -> b = 1 ; 59 p -> c = 2 ; 60 p -> d = 3 ; 61 62 p -> displayA(); 63 cout << endl; 64 p -> displayB(); 65 cout << endl; 66 p -> displayC(); 67 cout << endl; 68 p -> displayD(); 69 cout << endl; 70 }
复制代码

 

好了就写到这吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值