1

Not 100% sure whether my question is worded correctly as I don't fully understand my problem.

For my course I need to create my own smart pointer to clean up after itself.

Here's my code so far:

Header:

class Test
{
    public:
        Test()
        {
            m_iTest1 = 4;
            m_iTest2 = 3;
            m_iTest3 = 2;
            m_iTest4 = 1;
        }

        Test (int a, int b, int c, int d)
        {
            m_iTest1 = a;
            m_iTest2 = b;
            m_iTest3 = c;
            m_iTest4 = d;
        }

        Test(const Test& a_oTest)
        {
            m_iTest1 = a_oTest.m_iTest1;
            m_iTest2 = a_oTest.m_iTest2;
            m_iTest3 = a_oTest.m_iTest3;
            m_iTest4 = a_oTest.m_iTest4;
        }

        ~Test(){;}

        int m_iTest1;
        int m_iTest2;
        int m_iTest3;
        int m_iTest4;
};

template<class T>
class SmartData
{
    public:
        template<class T> friend class SmartPointer;

        SmartData();
        SmartData(const T& a_oData);
        ~SmartData();

        T operator * () const;
        unsigned int GetCount(){return m_uiCount;}

    protected:
        void IncrementCount(){++m_uiCount;}

        void DecrementCount();

        void DeleteThis();

        unsigned int m_uiCount;
        T* m_poData;
};

template<class T>
class SmartPointer
{
    public:
        SmartPointer();
        SmartPointer(SmartData<T>& a_oSmartData);
        SmartPointer(const SmartPointer& a_oSmartPointer);
        ~SmartPointer();

        SmartPointer<T>& operator = (const SmartPointer<T>& a_oSmartPointer);

        T operator *() const;
        SmartData<T>* operator ->() const;

        unsigned int GetCount() const;      

    private:
        SmartData<T>* m_poSmartData;
};

#include "smartpointer.inl"

Inline file:

template<class T>
SmartData<T>::SmartData()
{
    m_uiCount = 0;
    m_poData = new T();
}

template<class T>
SmartData<T>::SmartData(const T& a_oData)
{
    m_uiCount = 0;
    m_poData = new T(a_oData);
}

template<class T>
SmartData<T>::~SmartData()
{
    if (m_poData)
    {
        delete m_poData;
    }
}

template<class T>
T SmartData<T>::operator * () const
{
    return *m_poData;
}

template<class T>
void SmartData<T>::DecrementCount()
{
    if (m_uiCount - 1 == 0 || m_uiCount == 0)
    {
        DeleteThis();

        return;
    }

    --m_uiCount;    
}

template<class T>
void SmartData<T>::DeleteThis()
{
    if (m_poData)
    {
        delete m_poData;
        m_poData = 0;
    }
}

template<class T>
SmartPointer<T>::SmartPointer()
{
    m_poSmartData = new SmartData<T>();
    m_poSmartData->IncrementCount();
}

template<class T>
SmartPointer<T>::SmartPointer(SmartData<T>& a_oSmartData)
{
    m_poSmartData = &a_oSmartData;
    m_poSmartData->IncrementCount();
}

template<class T>
SmartPointer<T>::SmartPointer(const SmartPointer& a_oSmartPointer)
{
    m_poSmartData = a_oSmartPointer.a_oSmartData;
    m_poSmartData->IncrementCount();
}

template<class T>
SmartPointer<T>::~SmartPointer()
{
    m_poSmartData->DecrementCount();
    m_poSmartData = 0;
}

template<class T>
SmartPointer<T>& SmartPointer<T>::operator = (const SmartPointer<T>& a_oSmartPointer)
{
    m_poSmartData = a_oSmartPointer.m_poSmartData;
    m_poSmartData->IncrementCount();
}

template<class T>
T SmartPointer<T>::operator *() const
{
    return *m_poSmartData->m_poData;
}

template<class T>
SmartData<T>* SmartPointer<T>::operator ->() const
{
    return m_poSmartData;
}

template<class T>
unsigned int SmartPointer<T>::GetCount() const
{
    return m_poSmartData->m_uiCount;
}

main.cpp

void SomeFunction1(SmartData<Test>& a_SmartData)
{
    SmartPointer<Test> oSmartPointer2(a_SmartData);
}

void main()
{
    SmartData<int> oSmartData1(5);

    if (1)
    {       
        SmartPointer<int> oSmartPointer1(oSmartData1);

        int iTemp1 = oSmartPointer1->GetCount();
        int iTemp2 = *oSmartPointer1;
        int iTemp3 = *oSmartData1;
    }

    if (1)
    {
        SmartData<int> oSmartData2(5);
    }

    SmartData<Test> oSmartData3;

    (*oSmartData3).m_iTest1 = 5; //Does not work

    if (1)
    {
        SmartData<Test> oSmartData4(oSmartData3);

        SomeFunction1(oSmartData3);

        //oSmartData4 still exits
    }
}

Everything works fine, the data is cleaned up after itself and I get no leaks... except for one line:

(*oSmartData3).m_iTest1 = 5;

I'm compiling with visual studio, and when I place the "." after "(*oSmartData3)"... "m_iTest1" comes up correctly. Except I get an error: error C2106: '=' : left operand must be l-value

I'm not sure why this doesn't work or what to change so it does work.

1
  • 1
    This is not related to your problem, but your SmartPointer<T>::operator = (const SmartPointer<T>& a_oSmartPointer) has a bug, where it doesn't decrement the SmartData before it reassigns it's internal data. That'll cause major problems. Commented Aug 16, 2011 at 6:00

3 Answers 3

4

Look closer at the declaration of operator*() in SmartData:

T operator * () const;

This means that this operator is returning an object of type T, which is a copy of m_poSmartData->m_poData. It is a temporary object in this context:

(*oSmartData3).m_iTest1 = 5; //Does not work

Of course, you cannot assign a value to a temporary object, because it is not an l-value. Read more about what l-values and r-values are here: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc05lvalue.htm

I would suggest that you return a reference to m_poSmartData->m_poData in operator*() (if I'm understanding correctly what you are trying to do).

Sign up to request clarification or add additional context in comments.

Comments

2

Your T operator *() const is returning a temporary object (i.e. a copy), which is not an l-value (cannot be assigned to). Return a reference instead:

T& operator *() const;

Comments

0

Does this work:

 oSmartData3.m_iTest1 = 5;

1 Comment

No, since I'm trying to access the stored classes member variable... I overloaded the "*" operator to get at it. oSmartData3 is an instance of my SmartData class and has no member "m_iTest1"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.