Home Custom dynamic_pointer_cast implementation in C++98
Reply: 1

Custom dynamic_pointer_cast implementation in C++98

Nathan Owen
1#
Nathan Owen Published in 2018-01-13 00:00:40Z

Requisite explanation: I have to use C++98, no choice, yes I have asked my chip vendor for an updated toochain, no I will not be getting C++11 anytime soon (cry).

Problem: I have implemented my own shared pointer (queue rants on why I should not do that) based on this. However, I am having trouble implementing my own dynamic_pointer_cast function, or, at least, I am having trouble getting my implementation to link properly.

Here is my code (in a header file) implementation:

#ifndef __SMART_POINTER_HEADER__
#define __SMART_POINTER_HEADER__

class RC
{
    private:
        int count; // Reference count

    public:
        void AddRef()
        {
            // Increment the reference count
            __sync_add_and_fetch( &count, 1 );
        }

        int Release()
        {
            // Decrement the reference count and
            // return the reference count.
            return __sync_sub_and_fetch( &count, 1 );
        }
};

template < typename T > class SmartPointer
{
    private:
        T* pData;       // pointer
        RC* reference; // Reference count

    public:
        SmartPointer() : pData( 0 ), reference( 0 )
        {
            // Create a new reference
            reference = new RC();
            // Increment the reference count
            reference->AddRef();
        }

        SmartPointer( T* pValue ) : pData( pValue ), reference( 0 )
        {
            // Create a new reference
            reference = new RC();
            // Increment the reference count
            reference->AddRef();
        }

        SmartPointer( const SmartPointer<T>& sp ) : pData( sp.pData ), reference( sp.reference )
        {
            // Copy constructor
            // Copy the data and reference pointer
            // and increment the reference count
            reference->AddRef();
        }

        ~SmartPointer()
        {
            // Destructor
            // Decrement the reference count
            // if reference become zero delete the data
            if ( reference->Release() == 0 )
            {
                delete pData;
                delete reference;
            }
        }

        T& operator* ()
        {
            return *pData;
        }

        T* operator-> ()
        {
            return pData;
        }

        SmartPointer<T>& operator = ( const SmartPointer<T>& sp )
        {
            // Assignment operator
            if ( this != &sp ) // Avoid self assignment
            {
                // Decrement the old reference count
                // if reference become zero delete the old data
                if ( reference->Release() == 0 )
                {
                    delete pData;
                    delete reference;
                }

                // Copy the data and reference pointer
                // and increment the reference count
                pData = sp.pData;
                reference = sp.reference;
                reference->AddRef();
            }

            return *this;
        }

        bool operator ! () const
        {
            return ( NULL != reference );
        }

        bool operator == ( const SmartPointer<T>& other )
        {
            return( reference == other.reference );
        }

        bool operator == ( void * other )
        {
            return( reference == other );
        }

        bool operator != ( const SmartPointer<T>& other )
        {
            return( reference != other.reference );
        }

        bool operator != ( void * other )
        {
            return( reference != other );
        }

        template <class Y, class U> friend SmartPointer<Y> dynamic_smart_pointer_cast( const SmartPointer<U>& sp );
};

template <class T, class U> SmartPointer<T> dynamic_smart_pointer_cast ( const SmartPointer<U *>& sp )
{
    SmartPointer<T> new_sp;
    new_sp.pData = dynamic_cast<T*>( sp.pData );

    if( NULL != new_sp.pData )
    {
        delete new_sp.pData;
        delete new_sp.reference;
        sp.reference->addRef();
        new_sp.pData = sp.pData;
        new_sp.reference = sp.reference;
    }

    return new_sp;
}

#endif

Please let me know if you see any issues in the SmartPointer, I basically copied it from here and added the missing functions I needed.

My problem is that when I call dynamic_smart_pointer_cast with:

dynamic_smart_pointer_cast< BaseClass >( DerivedClassInstance )

The linker outputs:

undefined reference to `SmartPointer<BaseClass> dynamic_smart_pointer_cast<BaseClass, DerivedClass>(SmartPointer<DerivedClass> const&)'

I have put the definition for the template function in the included header file so I am not sure why I would be getting this linker error. Does anyone know what my problem might be?

Also feel free to review my dynamic_smart_pointer_cast code as I am fairly sure it can be improved and likely has issues.

SoronelHaetir
2#
SoronelHaetir Reply to 2018-01-13 00:10:56Z

In:

dynamic_smart_pointer_cast ( const SmartPointer<U *>& sp )

get rid of the * inside the <>

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.310232 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO