Reference count for More Effective C ++

Source: Internet
Author: User

Reference counting reminds me of Java. If you want to use C ++ to implement Java capabilities, Reference counting is indispensable. Reference counting can save program operation costs, and the cost of a large number of constructor, destructor, allocation, release, and copy is omitted.

  Implementation

ClassRCObject
{
Public:
RCObject (): refCount (0), retriable (true ){}
RCObject (constRCObject &): refCount (0), retriable (true ){}
RCObject & operator = (constRCObject & rhs) {return * this ;}
Virtual ~ RCObject () = 0;
Void AddReference () {++ refCount ;}
Void RemoveReference () {if (-- refCount = 0) deletethis ;}

Void markunretriable () {retriable = false ;}
Bool isShareable () const {returnshareable ;}
Bool isShared () const {returnrefCount> 1 ;}
Private:
Int refCount;
Bool retriable;
};
RCObject ::~ RCObject (){}

Template <classT>
Class RCPtr
{
Public:
RCPtr (T * realPtr = 0): pointee (realPtr) {init ();}
RCPtr (constRCPtr & rhs): pointee (rhs. pointee) {init ();}
~ RCPtr () {if (pointee) pointee-> RemoveReference ();}
RCPtr & operator = (constRCPtr & rhs)
{
If (pointee! = Rhs. pointee)
{
If (pointee)
Pointee-> RemoveReference ();
Pointee = rhs. pointee;
Init ();
}
Return * this;
}
T * operator-> () const {returnpointee ;}
T & operator * () const {return * pointee ;}
Private:
T * pointee;
Void init ()
{
If (pointee = 0)
Return;
If (pointee-> isShareable () = false)
Pointee = newT (* pointee );
Pointee-> AddReference ();
}
};

Class String
{
Public:
String (const char * value = ""): value (newStringValue (value )){}
Const char & operator [] (intnIndex) const
{
Return value-> data [nIndex];
}
Char & operator [] (intnIndex)
{
If (value-> isShared ())
Value = newStringValue (value-> data );
Value-> markunretriable ();
Returnvalue-> data [nIndex];
}
Protected:
Private:
Struct StringValue: publicRCObject
{
Char * data;
String Value (constchar * initValue)
{
Init (initValue );
}
String Value (constStringValue & rhs)
{
Init (rhs. data );
}
Void init (constchar * initValue)
{
Data = newchar [strlen (initValue) + 1];
Strcpy (data, initValue );
}
~ String Value ()
{
Delete [] data;
}
};
RCPtr <StringValue> value;
};

This is the String implementation provided by Meyers. However, my opinion is that if there is no special need, it is best not to use reference count for stirng, because the cost of synchronization in a multi-threaded program is greater than the benefit of the reference count itself, it is not worth the candle.

What if StringValue is a ready-made class and cannot be modified? You can use delegation. The following is a typical implementation:

ClassRCObject
{
Public:
RCObject (): refCount (0), retriable (true ){}
RCObject (constRCObject &): refCount (0), retriable (true ){}
RCObject & operator = (constRCObject & rhs) {return * this ;}
Virtual ~ RCObject () = 0;
Void AddReference () {++ refCount ;}
Void RemoveReference () {if (-- refCount = 0) deletethis ;}

Void markunretriable () {retriable = false ;}
Bool isShareable () const {returnshareable ;}
Bool isShared () const {returnrefCount> 1 ;}
Private:
Int refCount;
Bool retriable;
};
RCObject ::~ RCObject (){}

Template <classT>
Class RCIPtr
{
Public:
RCIPtr (T * realPtr = 0): counter (new CountHolder)
{
Counter-> pointee = realPtr;
Init ();
}
RCIPtr (constRCIPtr & rhs): counter (rhs. counter)
{
Init ();
}
~ RCIPtr ()
{
Counter-> RemoveReference ();
}
RCIPtr & operator = (constRCIPtr & rhs)
{
If (counter! = Rhs. counter)
{
Counter-> RemoveReference ();
Counter = rhs. counter;
Init ();
}
Return * this;
}
ConstT * operator-> () const
{
Returncounter-> pointee;
}
T * operator-> ()
{
MakeCopy ();
Returncounter-> pointee;
}
ConstT & operator * () const
{
Return * (counter-> pointee );
}
T & operator *()
{
MakeCopy ();
Return * (counter-> pointee );
}
Private:
Struct CountHolder: publicRCObject
{
~ Count Holder () {deletepointee ;}
T * pointee;
};
Count Holder * counter;
Void init ()
{
If (counter-> isShareable () = false)
{
T * oldValue = counter-> pointee;
Counter = newCountHolder;
Counter-> pointee = newT (* oldValue );
}
Counter-> AddReference ();
}
Void makeCopy ()
{
If (counter-> isShared ())
{
T * oldValue = counter-> pointee;
Counter-> RemoveReference ();
Counter = newCountHolder;
Counter-> pointee = newT (* oldValue );
Counter-> AddReference ();
}
}
};
Class Widget
{
Public:
Widget (intSize ){}
Widget (constWidget & rhs ){}
~ Widget (){}
Widget operator = (const Widget & rhs ){}
Void doThis () {printf ("doThis ()"); return ;}
Int showThat () const {printf ("showThat ()"); return 0 ;}
Protected:
Private:
Inti;
};

Class RCWidget
{
Public:
RCWidget (intsize): value (newWidget (size )){}
Void doThis () {value-> doThis ();}
Int showThat () const {returnvalue-> showThat ();}
Protected:
Private:
RCIPtr <Widget> value;
};

   Evaluation

It is necessary to implement reference counting. In not all cases, it is appropriate to use reference counting. The applicable situations are as follows:

A relatively large number of objects share a relatively small amount of real values.

The cost of generating or destroying the object's real value is very high, or it occupies a lot of memory.

But remember that even Java will have a memory leak. Don't expect a small reference count (simple implementation above) to avoid the same problem.

Reference counting is a very profound technique. Think about Java, so you need to be cautious. I hope it will bring optimization in programming.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.