0

私の抽象参照カウンタークラス:

template<class T>
class ReferenceCounter
{
public:

    ReferenceCounter();
    ~ReferenceCounter();

    void addRef();
    void release();

    uint32 getCountReferences() const;

protected:
    int32* pCountReferences;

    virtual void destroyObject() = 0;
    virtual void shallowCopy(const T& rhs) = 0;
};

template<class T>
inline ReferenceCounter<T>::ReferenceCounter() 
{
    pCountReferences = new int32;
    *pCountReferences = 1;
}

template<class T>
inline ReferenceCounter<T>::~ReferenceCounter() 
{
    if(pCountReferences != NULL && *pCountReferences == 0)
    {
        delete pCountReferences;
        pCountReferences = NULL;
    }
}

template<class T>
inline void ReferenceCounter<T>::addRef()
{
    debug_assert((*pCountReferences) >= 0, "Incorrect value of count references");
    ++(*pCountReferences);
}

template<class T>
inline void ReferenceCounter<T>::release()
{
    debug_assert((*pCountReferences) > 0, "Incorrect value of count references");
    (*pCountReferences)--;

    if(pCountReferences != NULL && *pCountReferences == 0)
    {
        destroyObject();
    }
}

template<class T>
inline uint32 ReferenceCounter<T>::getCountReferences() const
{
    return *pCountReferences;
}

これは私のスマートポインタです:

template<class T>
class SmartPtr
{
public:
    SmartPtr();
    SmartPtr(T* pInst);
    SmartPtr(const SmartPtr<T>& rhs);
    ~SmartPtr();

    void operator = (const SmartPtr<T>& rhs);
    T* operator -> () const;
    T* getData() const;

    bool isNULL() const;

private:
    T* pInst;
};

template<class T>
SmartPtr<T>::SmartPtr() : pInst(NULL) {}

template<class T>
SmartPtr<T>::SmartPtr(T* pInst) : pInst(pInst) {}

template<class T>
SmartPtr<T>::~SmartPtr() 
{
    if(pInst != NULL)
    {
        pInst->release();
    }
}

template<class T>
SmartPtr<T>::SmartPtr(const SmartPtr<T>& rhs)
{
    this->pInst = rhs.pInst;
    if(pInst != NULL)
    {
        pInst->addRef();
    }
}

template<class T>
void SmartPtr<T>::operator= (const SmartPtr<T>& rhs)
{
    this->pInst = rhs.pInst;
    if(pInst != NULL)
    {
        pInst->addRef();
    }
}

template<class T>
T* SmartPtr<T>::operator->() const
{
    return pInst;
}

template<class T>
T* SmartPtr<T>::getData() const
{
    return pInst;
}

template<class T>
bool SmartPtr<T>::isNULL() const
{
    return pInst == NULL;
}

コードのテストがあります:

#include <iostream>
#include "ReferenceCounter.h"
#include "SmartPtr.h"

using namespace std;

class B;

class A : public ReferenceCounter<A>
{
public:
    A();
    A(const A& rhs);
    ~A();

    SmartPtr<B> getB();
    void operator = (const A& rhs);

    private:
    void destroyObject();
    void shallowCopy(const A& rhs);
 };

class B : public ReferenceCounter<B>
{
private:
    void destroyObject() {} ;
    void shallowCopy(const B& rhs) {};
};

A::A()
{
    cout << "Create object" << endl;
}

A::A(const A& rhs)
{
    shallowCopy(rhs);
    addRef();
    cout << "copy constructor " << endl;
}

A::~A()
{
    release();
}

void A::destroyObject()
{
    cout << "destroy" << endl;
}

void A::shallowCopy(const A& rhs)
{
    this->pCountReferences = rhs.pCountReferences;
}

void A::operator = (const A& rhs)
{
    shallowCopy(rhs);
    addRef();
    cout << "operator = " << endl;
}

SmartPtr<B> A::getB()
{
    return SmartPtr<B>(new B());
}

SmartPtr<A> getA()
{
    SmartPtr<A> a(new A());
    return a;
}

int main()
{
    getA();
    return 0;
}

このコードは機能しますが、このコードをデバッグするときに、以下ではスマートポインターのコピーコンストラクターとは呼ばれません。以下でどのような問題が発生しますか?

int main()
{
   A a;
   a.getB();
}
4

1 に答える 1

0

戻り値の最適化については、こちらをご覧ください。

コンパイラーは、返される一時オブジェクトのコピーを排除することを許可されています。

C ++ 11では、オブジェクトを移動する可能性もあります。移動セマンティクスとは何ですか?を参照してください。説明のために。

更新

これはまったく問題ではなく、コンパイラの最適化だけです。

コンストラクタとデストラクタで特別なことが行われていない限り、この最適化を妨げる必要はありません。代わりにこれを許可する必要があります。これにより、1つのコンストラクタと1つのデストラクタ呼び出しをスキップすることで、プログラムの実行が高速化されます。

于 2013-01-05T21:47:45.960 に答える