用c++简单实现智能指针 用c简单实现智能指针什么是智能指针?答案相当简单;智能指针是聪明的普通指针。这是
用c++简单实现智能指针
用c++简单实现智能指针
什么是智能指针?答案相当简单;智能指针是聪明的普通指针。这是什么意思?实际上,智能指针是一些对象,表现出普通指针的功能但是比普通指针多做了一些事情。这些对象像普通指针一样灵活,并且管理对象有自己的优点(比如构造器和自动析构)。智能指针解决了普通指针的一些问题。
普通指针的问题。
我们使用C++语言中的指针,最常见的问题是什么?内存管理吧,请看下面的代码:
char* pName = new char[1024];…SetName(pName);……if(null != pName){ delete[] pName; }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;}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小时前
- 很喜欢博主的文章,刚刚用豆约翰博客备份专家备份了您的全部博文。
