青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 55  文章 - 15  trackbacks - 0
<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用鏈接

留言簿

隨筆分類

隨筆檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

PS:本文為轉(zhuǎn)載。鏈接地址:http://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c 

Introduction

What are smart pointers? The answer is fairly simple; a smart pointer is a pointer which is smart. What does that mean? Actually, smart pointers are objects which behave like pointers but do more than a pointer. These objects are flexible as pointers and have the advantage of being an object (like constructor and destructors called automatically). A smart pointer is designed to handle the problems caused by using normal pointers (hence calledsmart).

Problems with pointers

What are the common problems we face in C++ programs while using pointers? The answer is memory management. Have a look at the following code:

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

How many times have we found a bug which was caused because we forgot to delete pName. It would be great if someone could take care of releasing the memory when the pointer is not useful (we are not talking about the garbage collector here). What if the pointer itself takes care of that? Yes, that’s exactly what smart pointers are intended to do. Let us write a smart pointer and see how we can handle a pointer better.

We shall start with a realistic example. Let’s say we have a class called Person which is defined as below.

 Collapse | Copy Code
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",);         }  };

Now we shall write the client code to use Person.

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

Now look at this code, every time I create a pointer, I need to take care of deleting it. This is exactly what I want to avoid. I need some automatic mechanism which deletes the pointer. One thing which strikes to me is a destructor. But pointers do not have destructors, so what? Our smart pointer can have one. So we will create a class calledSP which can hold a pointer to the Person class and will delete the pointer when its destructor is called. Hence my client code will change to something like this:

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

Note the following things:

  • We have created an object of class SP which holds our Person class pointer. Since the destructor of the SPclass will be called when this object goes out of scope, it will delete the Person class pointer (as its main responsibility); hence we don’t have the pain of deleting the pointer.
  • One more thing of major importance is that we should be able to call the Display method using the SP class object the way we used to call using the Person class pointer, i.e., the class should behave exactly like apointer.

Interface for a smart pointer

Since the smart pointer should behave like a pointer, it should support the same interface as pointers do; i.e., they should support the following operations.

  • Dereferencing (operator *)
  • Indirection (operator ->)

Let us write the SP class now.

 Collapse | Copy Code
class SP { private:     Person*    pData; // pointer to person class public:     SP(Person* pValue) : pData(pValue)     {     }     ~SP()     {         // pointer no longer requried         delete pData;     }      Person& operator* ()     {         return *pData;     }      Person* operator-> ()     {             return pData;     } };

This class is our smart pointer class. The main responsibility of this class is to hold a pointer to the Person class and then delete it when its destructor is called. It should also support the interface of the pointer.

Generic smart pointer class

One problem which we see here is that we can use this smart pointer class for a pointer of the Person class only. This means that we have to create a smart pointer class for each type, and that’s not easy. We can solve this problem by making use of templates and making this smart pointer class generic. So let us change the code like this:

 Collapse | Copy Code
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.. }

Now we can use our smart pointer class for any type of pointer. So is our smart pointer really smart? Check the following code segment.

 Collapse | Copy Code
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(); }

Look what happens here. p and q are referring to the same Person class pointer. Now when q goes out of scope, the destructor of q will be called which deletes the Person class pointer. Now we cannot call p->Display();since p will be left with a dangling pointer and this call will fail. (Note that this problem would have existed even if we were using normal pointers instead of smart pointers.) We should not delete the Person class pointer unless no body is using it. How do we do that? Implementing a reference counting mechanism in our smart pointer class will solve this problem.

Reference counting

What we are going to do is we will have a reference counting class RC. This class will maintain an integer value which represents the reference count. We will have methods to increment and decrement the reference count.

 Collapse | Copy Code
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;     } };

Now that we have a reference counting class, we will introduce this to our smart pointer class. We will maintain apointer to class RC in our SP class and this pointer will be shared for all instances of the smart pointer which refers to the same pointer. For this to happen, we need to have an assignment operator and copy constructor in ourSP class.

 Collapse | Copy Code
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()     {         // 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;     } };

Let us have a look at the client code.

 Collapse | Copy Code
void 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 }

When we create a smart pointer p of type Person, the constructor of SP will be called, the data will be stored, and a new RC pointer will be created. The AddRef method of RC is called to increment the reference count to 1. Now SP q = p; will create a new smart pointer q using the copy constructor. Here the data will be copied and the reference will again be incremented to 2. Now r = p; will call the assignment operator to assign the value of p to q. Here also we copy the data and increment the reference count, thus making the count 3. When r and q go out of scope, the destructors of the respective objects will be called. Here the reference count will be decremented, but data will not be deleted unless the reference count becomes zero. This happens only when the destructor of p is called. Hence our data will be deleted only when no body is referring to it.

Applications

Memory leaks: Using smart pointers reduces the work of managing pointers for memory leaks. Now you could create a pointer and forget about deleting it, the smart pointer will do that for you. This is the simplest garbage collector we could think of.

Exceptions: Smart pointers are very useful where exceptions are used. For example, look at the following code:

 Collapse | Copy Code
void MakeNoise() {     Person* p = new Person("Scott", 25);     p->Shout();     delete p; }

We are using a normal pointer here and deleting it after using, so every thing looks okay here. But what if our Shoutfunction throws some exception? delete p; will never be called. So we have a memory leak. Let us handle that.

 Collapse | Copy Code
void MakeNoise() {     Person* p = new Person("Scott", 25);     try     {         p->Shout();     }     catch(...)     {         delete p;         throw;     }     delete p; }

Don't you think this is an overhead of catching an exception and re-throwing it? This code becomes cumbersome if you have many pointers created. How will a smart pointer help here? Let's have a look at the same code if a smartpointer is used.

 Collapse | Copy Code
void MakeNoise() {     SP<Person> p(new Person("Scott", 25));     p->Shout(); }

We are making use of a smart pointer here; yes, we don’t need to catch the exception here. If the Shout method throws an exception, stack unwinding will happen for the function and during this, the destructor of all local objects will be called, hence the destructor of p will be called which will release the memory, hence we are safe. So this makes it very useful to use smart pointers here.

Conclusion

Smart pointers are useful for writing safe and efficient code in C++. Make use of smart pointers and take the advantage of garbage collection. Take a look at Scott Meyers' auto_ptr implementation in STL.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

posted on 2012-05-18 16:36 Dino-Tech 閱讀(217) 評論(0)  編輯 收藏 引用
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            女生裸体视频一区二区三区| 国产精品成人一区| 欧美激情一区二区三区不卡| 亚洲人成人99网站| 欧美日韩综合久久| 久久国产欧美日韩精品| 欧美激情亚洲一区| 亚洲欧美日韩中文在线制服| 国产手机视频精品| 欧美激情91| 亚洲欧美成人一区二区在线电影 | 亚洲激情影院| 麻豆九一精品爱看视频在线观看免费| 亚洲一区二区三区三| 蜜臀av一级做a爰片久久| 精品不卡一区| 欧美激情一区二区| 欧美三区视频| 午夜老司机精品| 欧美亚洲日本一区| 欧美/亚洲一区| 欧美日韩国产一区二区三区地区| 亚洲一区二区精品视频| 午夜精品美女久久久久av福利| 国产午夜精品在线| 亚洲精品在线观看视频| 国产片一区二区| 亚洲高清不卡在线| 欧美日韩在线三区| 久久亚洲国产精品日日av夜夜| 久久综合99re88久久爱| 亚洲女爱视频在线| 免费观看成人网| 久久精品国产在热久久| 欧美精品午夜视频| 久久综合色播五月| 国产欧美日韩视频| 最新国产成人在线观看 | 鲁大师成人一区二区三区| 一区二区三区四区国产| 久久久人成影片一区二区三区观看 | 欧美激情影音先锋| 久久免费偷拍视频| 国产精品久久久一区麻豆最新章节| 裸体歌舞表演一区二区| 国产日韩一级二级三级| 亚洲一级在线观看| 夜夜嗨av一区二区三区免费区| 久久久精品国产99久久精品芒果| 亚洲一区二区在| 欧美韩日精品| 亚洲第一久久影院| 91久久精品网| 久久综合九色综合久99| 久久免费少妇高潮久久精品99| 国产精品视频大全| 制服丝袜亚洲播放| 亚洲免费一在线| 欧美亚男人的天堂| 一本色道久久88综合亚洲精品ⅰ| 一本大道久久a久久精品综合| 模特精品在线| 亚洲激情精品| 亚洲乱码日产精品bd| 欧美极品在线观看| 99re66热这里只有精品4| 亚洲乱码精品一二三四区日韩在线 | 先锋影音久久久| 午夜精品久久久久久99热| 国产精品久久久久秋霞鲁丝| 亚洲一区三区在线观看| 亚洲欧美日本在线| 国产欧美日韩精品在线| 欧美综合二区| 久久综合九色欧美综合狠狠| 尤物精品在线| 欧美va亚洲va日韩∨a综合色| 亚洲国产激情| 亚洲视频在线观看三级| 国产精品一二三四| 久久精品国产999大香线蕉| 免费久久久一本精品久久区| 国产色婷婷国产综合在线理论片a| 亚洲欧美卡通另类91av | 亚洲经典视频在线观看| 欧美日韩精品一区二区天天拍小说 | 亚洲福利视频一区| 亚洲午夜一区| 国内成+人亚洲| 免费欧美高清视频| 一区二区三区日韩精品| 久久夜色精品国产欧美乱| 亚洲激情在线视频| 国产精品日韩一区二区三区| 久久精品在线| 夜夜爽99久久国产综合精品女不卡| 性欧美长视频| 亚洲韩日在线| 国产精品国产三级国产| 久久久水蜜桃| 在线一区观看| 欧美超级免费视 在线| 亚洲一区二区三| 韩国视频理论视频久久| 欧美日韩国产精品专区| 久久精品论坛| 亚洲视频一区二区在线观看| 久久中文久久字幕| 亚洲性线免费观看视频成熟| 在线观看欧美黄色| 国产精品剧情在线亚洲| 欧美福利影院| 久久久综合香蕉尹人综合网| 中文在线资源观看网站视频免费不卡| 久久综合伊人| 欧美专区第一页| 一区二区三区视频观看| 亚洲黄色一区| 狠狠爱成人网| 国产欧美91| 国产精品久久久久久av福利软件| 麻豆亚洲精品| 久久久久九九视频| 午夜亚洲伦理| 亚洲免费视频网站| 亚洲特级毛片| 在线视频精品一| 亚洲人成网在线播放| 欧美大片在线看免费观看| 久久九九免费| 久久爱www久久做| 性欧美大战久久久久久久免费观看| 亚洲最新中文字幕| 亚洲免费观看视频| 亚洲乱码国产乱码精品精| 亚洲国产日韩一区二区| 狠狠色综合网站久久久久久久| 国产精品一卡二卡| 国产精品综合久久久| 国产精品视频男人的天堂| 欧美性生交xxxxx久久久| 欧美日韩精品高清| 欧美日韩免费区域视频在线观看| 欧美成人免费全部观看天天性色| 久久午夜电影网| 久久蜜桃资源一区二区老牛 | 美女视频一区免费观看| 久久综合色8888| 玖玖综合伊人| 欧美激情2020午夜免费观看| 欧美电影在线观看完整版| 欧美aⅴ一区二区三区视频| 欧美3dxxxxhd| 欧美日韩另类综合| 国产精品毛片| 国语自产在线不卡| 亚洲国产综合91精品麻豆| 亚洲全黄一级网站| 一区二区三区视频观看| 亚洲免费影视| 久久亚洲欧洲| 欧美激情按摩在线| 日韩亚洲精品在线| 亚洲欧美大片| 久久久xxx| 欧美日韩精品一区| 国产日韩专区在线| 亚洲国产第一页| 在线一区视频| 久久久精品网| 亚洲国产精品va在线观看黑人| 夜夜嗨av一区二区三区| 久久国产精品99久久久久久老狼| 免费日本视频一区| 国产精品美女视频网站| 国产一区二区三区在线播放免费观看 | 亚洲视频999| 久久先锋影音av| 欧美天天视频| 亚洲第一中文字幕| 亚洲一区二区三区四区在线观看| 久久久久综合| 亚洲毛片一区| 久久色在线观看| 国产精品视频一区二区高潮| 一区二区三区在线观看欧美| 亚洲色诱最新| 狼人天天伊人久久| 亚洲视频日本| 欧美日韩18| 一区二区三区在线观看视频 | 激情一区二区| 午夜国产精品视频| 91久久久久久久久久久久久| 午夜精品久久久久久99热| 欧美日韩精品二区第二页| 亚洲激情社区| 久久久综合激的五月天| 亚洲网站在线播放| 欧美日韩精品一区二区三区|