开发者

Cannot assign int to member int of returned class

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<T开发者_Python百科est> 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.


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).


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;


Does this work:

 oSmartData3.m_iTest1 = 5;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜