dcsimg

Smart Pointer that supports subclassing

WEBINAR:
On-Demand

Application Security Testing: An Integral Part of DevOps


Until now all smart pointer implementations that I have seen didn't support assignment between base and derived class pointers. Here is an implementation that does support it. I give you two implementations of smart pointers:

1) Ptr<T> - This smart pointer assumes that 'T' support reference counting by deriving from IRefCount (which is also supplied).

2) SmartPtr<T> - This smart pointer is more generic than Ptr<T> while not assuming anything about the type 'T'. Being more generic costs having a small reference object created for each referenced object or type.

The following source code demonstrates the use of the two types of smart pointers templates.

#include <string>
#include <iostream>
#include "ptr.h"
#include "smartPtr.h"

using namespace std;

class Object;
class Host;

typedef Ptr<Host>			PHost;
typedef Ptr<Object>			PObject;

class Object : public IRefCount {
	public:
		Object (int id, const string& name) : m_name(name), m_id(id) {};
		const string& GetName () { return m_name; }
	protected:
		string	m_name;
		int		m_id;
};

class Host : public Object {
	public:
		Host (int id, const string& name, const string& hostName):
				m_hostName(hostName), Object (id, name) {};
		
	protected:
		string	m_hostName;
};

// The following two classes do not carry any
// reference counting inteface.
class Base {
	
};

class Derived : public Base {
	
};
	
typedef SmartPtr<Base>		PBase;
typedef SmartPtr<Derived>	PDerived;


void PrintName (PObject pObj)
{
	cout << pObj->GetName() >> endl;
}

// testSmartPtr
//
// demonstrate the SmartPtr<T> template. The
// Base and Derived classes are simple classes
// that don't support any reference counting.
//
void testSmartPtr ()
{	
	PDerived pDerived2;
	PBase pBase;

	PDerived pDerived = new Derived;
	
	// The Ptr<T> supports subclassing
	pBase = pDerived;
	pDerived2 = (PDerived&)pBase;
}

// testPtr
//
// demonstrate the Ptr<T> template. The Ptr<T>
// assumes that the referenced class 'T' supports
// the reference counting interface IRefCount.
//
void testPtr ()
{
	PHost pHost2;

	PHost pHost = new Host (1, "Wks5", "");

	// The Ptr<T> supports subclassing
	PObject pObject = pHost;		  
	pHost2 = (PHost&)pObject;
	PrintName (pHost2);
}

/**************************************************************
 | NAME: main
 **************************************************************/
void main ()
{
	testSmartPtr ();
	testPtr ();
}

Downloads

Download demo project - 6 Kb
Download source - 3 Kb


Comments

  • Trouble in std::list

    Posted by maquanwei on 04/26/2004 10:33pm

    I use this smart-point to a std::list, such as std::list>. When I use list::remove(somePtr), my compile give me a C2593 link error. I had to overide operator "==", but SmartPtr does not support compare between base-class's pointer and sub-class's pointer now. Do you have any suggest?

    Reply
  • No Error - Look more carefully!

    Posted by Legacy on 06/21/2002 12:00am

    Originally posted by: Erez Efrati

    If you just looked more carefully at the source code of the 
    
    template SmartPtr<T> and RefCountRep<T> you would have seen
    that:

    1) RefCountRep<T> is holding a pointer to the actual real
    class, and the following is a piece of the destructor code
    (taken from the SmartPtr.h) :

    template <class T>
    RefCountRep<T>::~RefCountRep ()
    {
    assert (m_count == 0);

    if (m_ptr != 0)
    delete m_ptr;
    }

    template <class T>
    void RefCountRep<T>::ReleaseRef ()
    {
    assert (m_count > 0);

    m_count--;
    if (m_count == 0)
    delete this;
    }


    2) Second and more important is that the whole idea about
    having a RefCountRep<T> template is not having the "real"
    class derive any special base class.

    Hope that answers it,


    Erez

    Reply
  • Error - your destructor in RefCountRep must be virtual

    Posted by Legacy on 12/18/2001 12:00am

    Originally posted by: NMTop40

    In RefCountRep, your destructor must be virtual! (This is serious). Presumably your template smart pointer will contain a class derived from RefCountRep.

    When it calls ReleaseRef() (on mine I call it Release to be consistent with COM, and indeed my smart pointer class can be used with CComObject classes, something CComPtr does not allow) - anyway - ReleaseRef() will call delete this on RefCountRep but if the destructor is not virtual it will not call the real class's destructor and there may be memory leaks if the real class has allocated memory.

    One other small matter - in mine I made the reference count mutable and the AddRef() and Release() functions const. This allows you to have reference counting on const pointers.


    Reply
  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • In order for IT service providers to succeed, it's paramount that they find a competitive advantage and continually develop new ways to find additional revenue streams. IT service providers need to be able to do it all for their clients – from managing entire technology infrastructures to responding quickly to a multitude of end-user needs. With a growing number of issues to resolve and limited technicians at hand, how can IT service providers operate efficiently while providing top-notch service …

  • The modern business IT ecosystem is extremely complex, with a myriad of connected devices, networks, and core business applications. Delivering a seamless and incident-free experience has never been more difficult — or more important — as every employee in an organization relies on a whole stack of technology to complete everyday tasks. A service management software-as-a-service (SaaS) solution can help businesses modernize and streamline their IT management operations. Read this Forrester Total …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date
×
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.