|
/*************************************************************************
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.
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.