首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

用c++容易实现智能指针

2013-04-12 
用c++简单实现智能指针 用c简单实现智能指针什么是智能指针?答案相当简单;智能指针是聪明的普通指针。这是

用c++简单实现智能指针

 

用c++简单实现智能指针

      什么是智能指针?答案相当简单;智能指针是聪明的普通指针。这是什么意思?实际上,智能指针是一些对象,表现出普通指针的功能但是比普通指针多做了一些事情。这些对象像普通指针一样灵活,并且管理对象有自己的优点(比如构造器和自动析构)。智能指针解决了普通指针的一些问题。

      普通指针的问题。

      我们使用C++语言中的指针,最常见的问题是什么?内存管理吧,请看下面的代码:

char* pName  = new char[1024];…SetName(pName);……if(null != pName){       delete[] pName; }


      好多次我们都会忘记释放pNme,并且管理释放这些不会再用到的指针将会是很大的工程。可不可以指针自身进行管理?当然,智能指针就可以做到。我们实现一个智能指针,看看智能指针如何处理的更好。      下面写一个实际例子,先写一个叫做Person的类。     
class Person{    int age;    char* pName;    public:        Person(): pName(0),age(0)        {        }        Person(char* pName, int age): pName(pName), age(age)        {        }        ~Person()        {        }        void Display()        {            printf("Name = %s Age = %d \n", pName, age);        }        void Shout()        {            printf("Ooooooooooooooooo");        } };

下面是客户端代码使用Person类。

void main(){    Person* pPerson  = new Person("Scott", 25);    pPerson->Display();    delete pPerson;}


现在我们来看这段代码,每当我创建一个指针,都要管理释放它。我要自动的释放它,智能指针可以。因此我们创建一个SP类来管理Person的对象,客户端的代码可以这样写:
void main(){    SP p(new Person("Scott", 25));    p->Display();    // Dont need to delete Person pointer..}

void main(){    SP p(new Person("Scott", 25));    p->Display();    // Dont need to delete Person pointer..}

注意:     1,我们创建了一个SP对象来管理Person的指针,当SP对象的作用域结束,会自动析构,它将释放Person的指针。     2,我们可以使用SP的对象p调用Display()函数,就像Person类的对象指针调用Display()函数,它的行为表现的像Person类的对象指针。智能指针接口   智能指针表现出指针的行为,所以应该支持如下运算符: Dereferencing (operator *)Indirection (operator ->)下面实现智能指针SP:
class SP{private:    Person*    pData; // pointer to person classpublic:    SP(Person* pValue) : pData(pValue)    {    }    ~SP()    {        // pointer no longer requried        delete pData;    }    Person& operator* ()    {        return *pData;    }    Person* operator-> ()    {            return pData;    }};

这就是我们智能指针,当它的析构函数被调用时会释放Person类的对象指针。它也支持类似于指针的操作。通用的智能指针但是有个问题,我们智能控制Person类,也就是说每一种类型我们都要实现一个智能指针。我们可以使用模版使它通用。
template < typename T > class SP{    private:    T*    pData; // Generic pointer to be stored    public:    SP(T* pValue) : pData(pValue)    {    }    ~SP()    {        delete pData;    }    T& operator* ()    {        return *pData;    }    T* operator-> ()    {        return pData;    }};void main(){    SP<Person> p(new Person("Scott", 25));    p->Display();    // Dont need to delete Person pointer..}

我们的智能指针这样就真的智能了吗?验证下面的代码:
void main(){    SP<Person> p(new Person("Scott", 25));    p->Display();    {        SP<Person> q = p;        q->Display();        // Destructor of Q will be called here..    }    p->Display();}

这样就会存在一个问题:p和q关联到了Person类的相同对象指针,当q结束它的作用域时会释放Person类的对象指针,我们用p调用Display()函数会因为垂悬指针而失败。我们应该在不使用它的时候再释放,智能指针中引入计数便可解决。计数器。下面实现一个计数器的类RC.
class RC{    private:    int count; // Reference count    public:    void AddRef()    {        // Increment the reference count        count++;    }    int Release()    {        // Decrement the reference count and        // return the reference count.        return --count;    }};

下面把计数器引入到我们的智能指针中:
template < typename T > class SP{private:    T*    pData;       // pointer    RC* reference; // Reference countpublic:    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()    {        // 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;    }};

在看看客户端的代码:
Collapse | Copy Codevoid main(){    SP<PERSON> p(new Person("Scott", 25));    p->Display();    {        SP<PERSON> q = p;        q->Display();        // Destructor of q will be called here..        SP<PERSON> r;        r = p;        r->Display();        // Destructor of r will be called here..    }    p->Display();    // Destructor of p will be called here     // and person pointer will be deleted}

 


1楼licoderli2小时前
很喜欢博主的文章,刚刚用豆约翰博客备份专家备份了您的全部博文。

热点排行
Bad Request.