Interfaces and their implementations, is this code legal/correct?

Discussion in 'C++' started by SenderX, Aug 28, 2003.

  1. SenderX

    SenderX Guest

    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.

    --
    The designer of the experimental, SMP and HyperThread friendly, AppCore
    library.

    http://AppCore.home.comcast.net
    SenderX, Aug 28, 2003
    #1
    1. Advertising

  2. SenderX

    SenderX Guest

    SenderX, Aug 28, 2003
    #2
    1. Advertising

  3. SenderX

    SenderX Guest

    SenderX, Aug 28, 2003
    #3
  4. SenderX

    SenderX Guest

    > Uhm, yes: try specific questions instead of "do this work for
    > me".


    I apologize.


    > * Submit the code to the online Comeau compiler, it's one of the
    > most standard-conforming around.


    Nice. So most compiler portability questions can be skipped, as long as the
    code in question compiled without warning in a "strictly conforming"
    compiler?


    > * Use smart-pointers such as std::auto_ptr and boost::shared_ptr
    > instead of raw C++ pointers.


    I was thinking of a templated smart pointer interface, IAutoPtr.

    So I can use one reference counted interface, and use it for C pointers and
    COM's IUnknown interface.

    Does that sound workable?


    P.S.

    How portable is the _asm keyword and 64-bit integers ( __int64 && long
    long ) among popular c++ compilers?

    My algos rely on a tiny bit of assembly.

    --
    The designer of the experimental, SMP and HyperThread friendly, AppCore
    library.

    http://AppCore.home.comcast.net
    SenderX, Aug 28, 2003
    #4
  5. On Thu, 28 Aug 2003 22:58:25 GMT, "SenderX" <> wrote:

    >> Uhm, yes: try specific questions instead of "do this work for
    >> me".

    >
    >I apologize.
    >
    >
    >> * Submit the code to the online Comeau compiler, it's one of the
    >> most standard-conforming around.

    >
    >Nice. So most compiler portability questions can be skipped, as long as the
    >code in question compiled without warning in a "strictly conforming"
    >compiler?


    No, but error- and warning-free compilation with a compiler such as Comeau
    is a good indication that the code is practically clean -- if it weren't,
    then the chances are near certainty that the compiler would catch something.

    But the only way to ensure portability is to (1) design and code for it,
    (2) compile with the relevant compilers and (3) test on the relevant systems.

    Systematically.




    >> * Use smart-pointers such as std::auto_ptr and boost::shared_ptr
    >> instead of raw C++ pointers.

    >
    >I was thinking of a templated smart pointer interface, IAutoPtr.
    >
    >So I can use one reference counted interface, and use it for C pointers and
    >COM's IUnknown interface.
    >
    >Does that sound workable?


    Not immediately. COM reference counting keeps the reference count in each
    referred object, ordinary C++ smart-pointers keep the count in the pointer
    object or in a shared helper object. Generally, nail => hammer, screw =>
    screwdriver, and so on.


    >How portable is the _asm keyword


    Not portable at all.


    > and 64-bit integers ( __int64 && long long ) among popular c++ compilers?


    Not at all, but in C99 (and possibly future C++0x) it's another story.



    >My algos rely on a tiny bit of assembly.


    Wrap it behind a clean C++ interface.
    Alf P. Steinbach, Aug 29, 2003
    #5
  6. SenderX

    SenderX Guest

    > No, but error- and warning-free compilation with a compiler such as Comeau
    > is a good indication that the code is practically clean


    I got a "compile succeeded" using strict mode. So I am currently on the
    correct path...


    > But the only way to ensure portability is to (1) design and code for it,
    > (2) compile with the relevant compilers and (3) test on the relevant

    systems.
    >
    > Systematically.


    Yep. ;(


    > >How portable is the _asm keyword


    Damn. Any special tricks to get assembly code to compile across different
    compilers? ;)


    > > and 64-bit integers ( __int64 && long long ) among popular c++

    compilers?
    >
    > Not at all, but in C99 (and possibly future C++0x) it's another story.


    Mmmk.


    > >My algos rely on a tiny bit of assembly.

    >
    > Wrap it behind a clean C++ interface.


    That would allow for a single interface that implements varying assembly
    code specific to different processors.

    // Interfaces

    class IAtomic
    -- CompareAndSwap(...) = 0;
    -- ExchangeAdd(...) = 0;


    // Specific processor implmenataions
    class CIA32Atomic : public IAtomic
    {
    ...
    };


    class CIA64Atomic : public IAtomic
    {
    ...
    };


    class CPowerPCAtomic : public IAtomic
    {
    ...
    };


    class CPowerPC64Atomic : public IAtomic
    {
    ...
    };


    class CAMD64Atomic : public IAtomic
    {
    ...
    };

    My lock-free code has to be portable across compiler, platform, and
    processor. I think C++ and this group can help me.

    Thanks.

    --
    The designer of the experimental, SMP and HyperThread friendly, AppCore
    library.

    http://AppCore.home.comcast.net
    SenderX, Aug 29, 2003
    #6
  7. On Fri, 29 Aug 2003 00:12:10 GMT, "SenderX" <> wrote:
    >
    >> >How portable is the _asm keyword

    >
    >Damn. Any special tricks to get assembly code to compile across different
    >compilers? ;)


    The usual "trick" is to write the assembly in -- assembly.

    Then link it into the application.

    E.g., parts of the C++ runtime library, for most any compiler, is
    implemented that way.
    Alf P. Steinbach, Aug 29, 2003
    #7
  8. SenderX

    Greg Comeau Guest

    In article <lOv3b.287479$Ho3.39520@sccrnsc03>, SenderX <> wrote:
    >> * Submit the code to the online Comeau compiler, it's one of the
    >> most standard-conforming around.

    >
    >Nice. So most compiler portability questions can be skipped,
    >as long as the code in question compiled without warning in
    >a "strictly conforming" compiler?


    Use one of the "zillion" non-strictly conforming modes
    of Comeau then if that is your concern. :)
    --
    Greg Comeau/4.3.3:Full C++03 core language + more Windows backends
    Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
    World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
    Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
    Greg Comeau, Aug 29, 2003
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike
    Replies:
    8
    Views:
    408
    A Bag Of Memes
    Jul 20, 2003
  2. Chris Mantoulidis
    Replies:
    3
    Views:
    414
    Jared Dykstra
    Dec 20, 2003
  3. Andreas Schmidt
    Replies:
    2
    Views:
    301
    David Harmon
    Apr 9, 2004
  4. Carramba

    is this legal declaration/not correct output

    Carramba, May 16, 2007, in forum: C Programming
    Replies:
    12
    Views:
    566
    David Thompson
    Jul 1, 2007
  5. Dan Stromberg
    Replies:
    2
    Views:
    399
    Mike Schilling
    Jan 3, 2008
Loading...

Share This Page