Click here to Skip to main content
15,884,176 members
Articles / Programming Languages / C++

A Smart Pointer Capable of Object Level Thread Synchronization and Reference Counting Garbage Collection

Rate me:
Please Sign up or sign in to vote.
4.89/5 (19 votes)
12 Jan 20008 min read 177.2K   1.8K   65  
A smart pointer wrapper class
/*************************************************************************
 FILE       : SmartPtrDemo.cpp

 Description: This project is intended to test the capabilities
			  of SmartPtr classes. Use this project under the 
			  same copyright as SmartPtr.h

 Created By : Stefan Tchekanov

*************************************************************************/
/* #    Revisions    # */


//////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <stdio.h>

//////////////////////////////////////////////////////////////////////

//	ASSERT needs to be defined before inclusion of SmartPtr.h
//	Because it is used inside it.
#define	ASSERT(p)
#include "SmartPtr.h"

//////////////////////////////////////////////////////////////////////

//	A base class
class B
{
public:
	B( char* data ) { m_data = data; };
	virtual ~B() {
		int i = 0;
	}

	virtual	void	print() {
		printf( "B : %s\n", m_data );
	};
	char*	m_data;
};
//////////////////////////////////////////////////////////////////////

//	A sub class (inherited from class B)
class A : public B
{
public:
	A( char* data ) : B(data) {};
	virtual ~A() {
		int i = 0;
	}

	virtual	void	print() {
		printf( "A : %s\n", m_data );
	};
};
//////////////////////////////////////////////////////////////////////

//	An independent class
class C
{
public:
	C( char* data ) : m_data( data ) {};
	virtual ~C() {
		int i = 0;
	}

	virtual	void	println() {
		printf( "C : %s\n", m_data );
	};
	char*	m_data;
};
//////////////////////////////////////////////////////////////////////

//	Thread data
class	T {
public:
	RefCountPtr<A>	m_pa;
};

//	It is more readable to read LPT than SyncRefCountPtr<T>
typedef		SyncRefCountPtr<T>	LPT;

//	structure used to gracefully pass parameters to the thread
struct	ThreadArgs {
public:
	LPT		m_ptr;
};
//////////////////////////////////////////////////////////////////////

DWORD WINAPI ThreadProc( LPVOID lpParam )
{
	ThreadArgs*	pargs = (ThreadArgs*)lpParam;
	LPT			pData = pargs->m_ptr;

	pData->m_pa->print();
	for( int i = 0; i < 200000; i++ )
	{
		pData->m_pa->m_data = "new text";
	}
	pData->m_pa->print();

	return	0;
}
//////////////////////////////////////////////////////////////////////

void	TestSynchroniztion()
{
	HANDLE	ahThread[2];
	DWORD	aThreadID[2];

	LPT	pData = new T;
	pData->m_pa = new A( "thread object" );

	ThreadArgs*	pargs = new ThreadArgs;
	pargs->m_ptr = pData;

	ahThread[0] = ::CreateThread( NULL, 0, ThreadProc, &pData, CREATE_SUSPENDED, &aThreadID[0] );
	ahThread[1] = ::CreateThread( NULL, 0, ThreadProc, &pData, CREATE_SUSPENDED, &aThreadID[1] );

	::ResumeThread( ahThread[0] );
	::ResumeThread( ahThread[1] );

	::WaitForMultipleObjects( 2, (HANDLE*)ahThread, TRUE, INFINITE );
	pData->m_pa->print();

	delete	pargs;
}
//////////////////////////////////////////////////////////////////////

void	TestRefCounting()
{
	int	i = 0;

	//	Test construction/destruction
	{
		A*	pa = new A( "A object" );
		A*	pa1 = new A( "A1 object" );
		B*	pb = new B( "Base object" );
		C*	pc = new C( "C object" );

		//	Regular construction
		RefCountPtr<A> a = pa;
		RefCountPtr<B> b = pb;
		RefCountPtr<B> b1 = b;
		
		//	pointer to Super (base) class receives
		//	an object of sub class                
		RefCountPtr<B> b2 = a;
		RefCountPtr<B> b3 = pa1;
		
		RefCountPtr<C> c = pc;
		//	the pointer receives
		//	an object of independent class                
		RefCountPtr<B> b4 = c;
//		RefCountPtr<B> b5 = pc;	//	illegal

		//	Comparison operator
		if( b2 == a ) {
			i = 1;
		}
	}

	//	Test assignment operatos
	{
		A*	pa = new A( "A object" );
		A*	pa1 = new A( "A1 object" );
		B*	pb = new B( "Base object" );
		C*	pc = new C( "C object" );

		RefCountPtr<A> a;
		RefCountPtr<B> b;
		RefCountPtr<B> b1;
		RefCountPtr<B> b2;
		RefCountPtr<B> b3;
		RefCountPtr<C> c;

		a = pa;
		b = pb;
		b1 = b;

		//	pointer to Super (base) class receives
		//	an object of sub class                
		b2 = a;
		b3 = pa1;

		c = pc;
		//	the pointer receives
		//	an object of independent class                
		b = c;
//		b1 = pc;	//	illegal

		b->m_data = "pppppp";
		a->print();
		b->print();

		pb = a;
		A	aa = *a;

		if( b == b2 ) {
			i = 2;
		}
		if( b != b2 ) {
			i = 3;
		}
		i = sizeof(b);
	}
}
//////////////////////////////////////////////////////////////////////

int main( int argc, char* argv[] )
{
	TestRefCounting();
	TestSynchroniztion();

	return 0;
}
//////////////////////////////////////////////////////////////////////

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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


Written By
Software Developer (Senior) Brosix
Bulgaria Bulgaria
Stefan does programming since his early ages more than 30 years ago. Later he began programming at his work and now he is very happy to work his hobby. He owns a Master's degree in Computer Science.

During his professional career, Stefan has worked with many technologies. His programming experience includes C/C++, Java, C#, PHP, JavaScript, MFC, ATL, ASP, ASP.NET, TCP/IP, SQL. He has worked with different operating systems: Windows, Linux, Mac OS X, iOS, Android, Solaris, FreeBSD, NetBSD and QNX.

Currently his professional interests are in building large scale distributed systems that operate over the Internet. This involves building server components as well as developing system level software.

More information about his current work can be found here: brosix.com - Enterprise Instant Messaging


Stefan is based in Plovdiv, Bulgaria. It is a very nice and peaceful place combined with an enjoyable weather.

Stefan has a wife and 2 children. He likes in his spear time to travel with his family to see new and interesting places.

Comments and Discussions