Click here to Skip to main content
Click here to Skip to main content

A Simple Smart Pointer

, 11 Jan 2000
Rate this:
Please Sign up or sign in to vote.
A template-based smart pointer implementation
  • Download demo project - 19 Kb
  • Download source files - 1.6 Kb
  • <!-- Article Starts -->

    Here is another smart pointer implementation. It's as easy as it gets.

    How to use it

    #include "/libs/idlsoft/smartptr.h"
    using namespace idllib;
    // in a body
        SmartPtr<CMyObject> ptr1(new CMyObject);  // construct from a pointer
        SmartPtr<CMyObject> ptr2(ptr1);   // construct from a smart pointer
        SmartPtr<CMyObject> ptr3;         // construct an empty one
        ptr3 = new CMyObject;                   // assign a pointer
        ptr1 = ptr3;                            // assign a smart pointer
        ptr1->method1();                     // call a method
        ptr2 = NULL;
        // etc ...    
    // in a function call
        void f(CMyObject *ob);                   // function declaration
        ...
        SmartPtr<CMyObject> ptr1(new CMyObject);
        f(ptr1);                                // function call
    // as a return value
        SmartPtr<CMyObject> f1()
        {
            return SmartPtr<CMyObject>(new CMyObject);
        }
        ...
        SmartPtr<CMyObject> ptr;
        ptr = f1();
    

    That's it!

    No need to worry about freeing the pointer, the object is deleted through a standard reference-counting mechanism.

    SmartPtr is the only class you really need here. It can point to anything that was allocated by the new operator.

    How NOT to use it

        // 1.
        SmartPtr<CMyObject> ptr;
        CMyObject ob;
        ptr = &ob;  // DON'T ! only memory allocated by new operator should be used
        // 2.
        SmartPtr<CMyObject> ptr1, ptr2;
        CMyObject *o2 = new CMyObject;
        ptr1 = o2;
        ptr2 = o2;  // DON'T ! unless CMyObject implements IRefCount
                    // try to use ptr1 = ptr2 instead, it's always safe;
    

    How it is implemented

    SmartPtr holds a pointer to a reference counting object. Every time we assign a value to SmartPtr it decrements the reference count on the current object and increments it for the new one. The reference counter for its part would delete the allocated object if the reference drops to zero.

    The reference counter can be either part of the allocated object (when we implement IRefCount) or a separate object (SmartPtr::__RefCounter) that holds a pointer to it.

    See next section for details.

    How to optimize memory usage

    In order to count references to the allocated object SmartPtr creates a special object, which means two memory allocations instead of one. If you want to optimize the memory usage just implement IRefCount in your class. You can do it yourself or use IRefCountImpl:

        class CMyObject : public CObject, public IRefCountImpl<CMyObject> {
        ...
        };
    
    In this case SmartPtr will use the built-in counter instead of a sparate one.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    Share

    About the Author

    Sandu Turcan

    United Kingdom United Kingdom
    No Biography provided

    Comments and Discussions

     
    Generaloptimization suggestion PinmemberShumy1-Dec-05 13:17 
    Generaldynamic_cast&lt;...&gt; (corrected) Pinmemberitaifrenkel3-Jan-04 21:25 
    I would like to downcast a smartpointer. For example:
     
    class A : public IRefCountImpl<A>
    class B : public A
     
    class B does not implement IRefCount<B> (but rather IRefCount<A>) and that causes many errors when casting the smart pointer.
     
    I tried to use Visual C++.NET 2003 covariant inheritance and virtual inheritance, but it did not compile. Any suggestions ?
     
    class A : public virtual IRefCountImpl<A>
    class B : public virtual A , public virtual IRefCountSubImpl<B,A>
     
    template <class T,class BT> class IRefCountSubImpl : public virtual IRefCountImpl<BT> {
          protected:
     
         virtual void __IncRefCount()
          {
              BT::__IncRefCount();
          }
          virtual void __DecRefCount()
          {
              BT::__DecRefCount();
          }
        
         //Overrides BT* GetPtr() const
         //Remember: Virtual base classes are not supported as covariant return types.
         virtual T * GetPtr() const
          {
                return ((T *)this);
          }
    };
    Generaldynamic_cast&lt;...&gt; Pinmemberitaifrenkel3-Jan-04 21:23 
    Generalsuggestion Pinmemberovolok27-Nov-03 16:56 
    Generalnitpick, optimization, and compliment Pinmemberpeterchen30-Sep-03 11:34 
    Generaluse in multiple Threads - thread safety PinmemberThomas George25-Jan-02 8:38 
    GeneralRe: use in multiple Threads - thread safety PinmemberThomas George25-Jan-02 8:50 
    GeneralRe: use in multiple Threads - thread safety PinsussAnonymous6-Aug-02 11:57 
    GeneralRe: use in multiple Threads - thread safety PinmemberThomas George6-Aug-02 13:08 
    GeneralRe: use in multiple Threads - thread safety PinmemberSandu Turcan6-Aug-02 15:19 
    GeneralSmartPtr -vs- STL Ptr Pinsussggeisen13-Jan-00 16:55 
    GeneralRe: SmartPtr -vs- STL Ptr PinsussSandu17-Jan-00 20:24 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

    | Advertise | Privacy | Terms of Use | Mobile
    Web04 | 2.8.141030.1 | Last Updated 12 Jan 2000
    Article Copyright 2000 by Sandu Turcan
    Everything else Copyright © CodeProject, 1999-2014
    Layout: fixed | fluid