2013年1月15日 星期二

auto_ptr and smart_ptr




//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <memory>
#include <string>
#include <iostream>
//---------------------------------------------------------------------------
class A
{
        std::string m_strAAA;
public:
        A():m_strAAA(""),x(0){std::cout <<"A:" << m_strAAA << std::endl;}
        A(const A &a):m_strAAA(a.m_strAAA),x(a.x){std::cout <<"A2:" << m_strAAA << std::endl;}
        A(const std::string &str):m_strAAA(str),x(0){std::cout <<"A3:" << m_strAAA << std::endl;}
        void print(){std::cout <<"[" << m_strAAA << "]"<< std::endl;}
        ~A(){std::cout <<"~A:" << m_strAAA << std::endl;}
        const std::string & GetAAA(){return m_strAAA;}
        int x;
};

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

    public:
    RC():count(0){}   // <-- initialize counter
    void AddRef()
    {
        // Increment the reference count
std::cout << "add_ref" << std::endl;
        count++;
    }

    int Release()
    {
std::cout << "release" << std::endl;
        // Decrement the reference count and
        // return the reference count.
        return --count;
    }
};
template < typename T > class SP
{
private:
    T*    pData;       // pointer
    RC* reference; // Reference count

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

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

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

    ~SP()
    {
std::cout << "content will be destructed!! [" << pData->GetAAA() << "]" << std::endl;
        // 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;
    }
    
    SP<T>& operator = (const SP<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;
    }
};
int main(int argc, char* argv[])
{
/*test auto_prt*/
        std::auto_ptr<A> aa;
        A a;
        {
        std::auto_ptr<A> aa1(new A("aa1"));
        aa1->print();
        aa=aa1;
        if(aa1.get()==0)
                std::cout << "aa1 ptr transfer to aa !!" << std::endl;
        }

        {
        std::auto_ptr<A> aa2(new A("aa2"));
        aa2->print();
        if(aa2.get()==0)
                std::cout << "aa2 ptr transfer to aa !!" << std::endl;
        }


/*test smart pointer*/
    SP<A> p(new A("Scott"));
    p->print();
    {
        SP<A> q = p;
        q->print();

        SP<A> r;
        r = p;
        r->print();
        
        // Destructor of q will be called here..
        // Destructor of r will be called here..
    }
    p->print();


    // Destructor of p will be called here 
    // and A pointer will be deleted



        return 0;
}
//---------------------------------------------------------------------------

結果顯示
/*test auto_prt*/
A:
A3:aa1
[aa1]
aa1 ptr transfer to aa !!
A3:aa2
[aa2]
~A:aa2

/*test smart pointer*/
A3:Scott
add_ref
[Scott]
add_ref
[Scott]
add_ref
release
add_ref
[Scott]
content will be destructed!! [Scott]  --> q
release
content will be destructed!! [Scott]  --> r
release
[Scott]
content will be destructed!! [Scott]  --> p

/* after return 0; */
release
~A:Scott
~A:
~A:aa1



reference: http://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c
http://caterpillar.onlyfun.net/Gossip/CppGossip/autoPtr.html


沒有留言:

張貼留言

文章分類