S
SenderX
I am a basically a life-long Win32 C programmer specializing in high-end
winsock servers.
Before I dive into portable C++ programming, I wanted to code up an example
of what I thought would be a workable Collection template library. The idea
is to design API's that operate on interfaces, and provide
multi-implementations to that "single" API. C++ Interfaces and
Implementations, seems to behave like Win32 COM objects?
Please look over the following code sketch, and point out ALL of the flaws
that render it non-portable and/or non-std:
Interfaces.cpp
--------------------
#ifndef NULL
# define NULL 0
#endif
// Collection objects
namespace Collections
{
// Forwards
template< typename T > class ICollection;
template< typename T > class IIterator;
template< typename T > class TNode;
template< typename T > class TStack;
// *** Interfaces ***
// The collection interface
template< typename T >
class ICollection
{
public:
virtual ~ICollection() {}
virtual void Push( T const* pObj, int iTimeout = 0 ) = 0;
virtual T* Pop( int iTimeout = 0 ) = 0;
virtual bool Pop( T const* pObj, int iTimeout = 0 ) = 0;
virtual IIterator< T >* RequestIterator() = 0;
virtual void ReleaseIterator( IIterator< T >* pIterator ) = 0;
};
// The iterator interface
template< typename T >
class IIterator
{
public:
// RAII
class CGuard
{
public:
CGuard( IIterator< T >* pIterator ) : m_pIterator( pIterator ) {}
~CGuard() { m_pIterator->GetCollection()->ReleaseIterator(
m_pIterator ); };
public:
IIterator< T >* operator ->() { return m_pIterator; }
private:
IIterator< T >* m_pIterator;
};
public:
virtual ~IIterator() {}
virtual void Next() = 0;
virtual void Prev() = 0;
virtual void Front() = 0;
virtual void Back() = 0;
virtual bool Eof() = 0;
virtual bool Bof() = 0;
virtual T* GetObj() = 0;
virtual ICollection< T >* GetCollection() = 0;
};
// *** Implmentation ***
// The collection node
template< typename T >
class TNode
{
public:
TNode( T const* pObj = NULL ) : m_pNext( NULL ), m_pObj( pObj ) {}
public:
TNode< T >* m_pNext;
T const* m_pObj;
};
// A stack object
template< typename T >
class TStack : public ICollection< T >
{
class CIterator;
private:
friend class CIterator;
class CIterator : public IIterator< T >
{
public:
CIterator( TStack< T >& Stack )
: m_Stack( Stack ),
m_pCurrent( NULL ),
m_pNext( NULL ),
m_pPrev( NULL ) {}
public:
void Next() {}
void Prev() {}
void Front() {}
void Back() {}
bool Eof()
{
return ( m_pCurrent && m_pCurrent->m_pNext ) ? true : false;
}
bool Bof()
{
return ( m_Stack.m_pFront == m_pCurrent ) ? true : false;
}
T* GetObj()
{
return ( m_pCurrent ) ? const_cast< T* >( m_pCurrent->m_pObj ) :
NULL;
}
ICollection< T >* GetCollection() { return &m_Stack; }
private:
TStack< T >& m_Stack;
TNode< T >* m_pCurrent;
TNode< T >* m_pNext;
TNode< T >* m_pPrev;
};
public:
void Push( T const* pObj, int iTimeout = 0 )
{
}
T* Pop( int iTimeout = 0 )
{
return NULL;
}
bool Pop( T const* pObj, int iTimeout = 0 )
{
return false;
}
IIterator< T >* RequestIterator()
{
return new CIterator( *this );
}
void ReleaseIterator( IIterator< T >* pIterator )
{
delete pIterator;
}
private:
TNode< T >* m_pFront;
};
}
// Test object
class CTest
{
public:
CTest() : m_Val1( 0 ) {}
public:
long m_Val1;
};
int main()
{
// Get the ICollection interface
Collections::ICollection< CTest >* pCol
= new Collections::TStack< CTest >;
{
// Get the ICollection's IIterator interface
Collections::IIterator< CTest >::CGuard
pIterator( pCol->RequestIterator() );
}
delete pCol;
return 0;
}
Thank you! =)
P.S.
I will be implementing some very fast, portable, lock-free algo's that will
use the interfaces posted here. If your interested I can post the code when
it is finished.
winsock servers.
Before I dive into portable C++ programming, I wanted to code up an example
of what I thought would be a workable Collection template library. The idea
is to design API's that operate on interfaces, and provide
multi-implementations to that "single" API. C++ Interfaces and
Implementations, seems to behave like Win32 COM objects?
Please look over the following code sketch, and point out ALL of the flaws
that render it non-portable and/or non-std:
Interfaces.cpp
--------------------
#ifndef NULL
# define NULL 0
#endif
// Collection objects
namespace Collections
{
// Forwards
template< typename T > class ICollection;
template< typename T > class IIterator;
template< typename T > class TNode;
template< typename T > class TStack;
// *** Interfaces ***
// The collection interface
template< typename T >
class ICollection
{
public:
virtual ~ICollection() {}
virtual void Push( T const* pObj, int iTimeout = 0 ) = 0;
virtual T* Pop( int iTimeout = 0 ) = 0;
virtual bool Pop( T const* pObj, int iTimeout = 0 ) = 0;
virtual IIterator< T >* RequestIterator() = 0;
virtual void ReleaseIterator( IIterator< T >* pIterator ) = 0;
};
// The iterator interface
template< typename T >
class IIterator
{
public:
// RAII
class CGuard
{
public:
CGuard( IIterator< T >* pIterator ) : m_pIterator( pIterator ) {}
~CGuard() { m_pIterator->GetCollection()->ReleaseIterator(
m_pIterator ); };
public:
IIterator< T >* operator ->() { return m_pIterator; }
private:
IIterator< T >* m_pIterator;
};
public:
virtual ~IIterator() {}
virtual void Next() = 0;
virtual void Prev() = 0;
virtual void Front() = 0;
virtual void Back() = 0;
virtual bool Eof() = 0;
virtual bool Bof() = 0;
virtual T* GetObj() = 0;
virtual ICollection< T >* GetCollection() = 0;
};
// *** Implmentation ***
// The collection node
template< typename T >
class TNode
{
public:
TNode( T const* pObj = NULL ) : m_pNext( NULL ), m_pObj( pObj ) {}
public:
TNode< T >* m_pNext;
T const* m_pObj;
};
// A stack object
template< typename T >
class TStack : public ICollection< T >
{
class CIterator;
private:
friend class CIterator;
class CIterator : public IIterator< T >
{
public:
CIterator( TStack< T >& Stack )
: m_Stack( Stack ),
m_pCurrent( NULL ),
m_pNext( NULL ),
m_pPrev( NULL ) {}
public:
void Next() {}
void Prev() {}
void Front() {}
void Back() {}
bool Eof()
{
return ( m_pCurrent && m_pCurrent->m_pNext ) ? true : false;
}
bool Bof()
{
return ( m_Stack.m_pFront == m_pCurrent ) ? true : false;
}
T* GetObj()
{
return ( m_pCurrent ) ? const_cast< T* >( m_pCurrent->m_pObj ) :
NULL;
}
ICollection< T >* GetCollection() { return &m_Stack; }
private:
TStack< T >& m_Stack;
TNode< T >* m_pCurrent;
TNode< T >* m_pNext;
TNode< T >* m_pPrev;
};
public:
void Push( T const* pObj, int iTimeout = 0 )
{
}
T* Pop( int iTimeout = 0 )
{
return NULL;
}
bool Pop( T const* pObj, int iTimeout = 0 )
{
return false;
}
IIterator< T >* RequestIterator()
{
return new CIterator( *this );
}
void ReleaseIterator( IIterator< T >* pIterator )
{
delete pIterator;
}
private:
TNode< T >* m_pFront;
};
}
// Test object
class CTest
{
public:
CTest() : m_Val1( 0 ) {}
public:
long m_Val1;
};
int main()
{
// Get the ICollection interface
Collections::ICollection< CTest >* pCol
= new Collections::TStack< CTest >;
{
// Get the ICollection's IIterator interface
Collections::IIterator< CTest >::CGuard
pIterator( pCol->RequestIterator() );
}
delete pCol;
return 0;
}
Thank you! =)
P.S.
I will be implementing some very fast, portable, lock-free algo's that will
use the interfaces posted here. If your interested I can post the code when
it is finished.