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

隨筆 - 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 閱讀(224) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            日韩视频一区二区三区| 在线观看精品| 欧美黄色日本| 国产一区二区三区直播精品电影 | 亚洲一区二区动漫| 老司机精品视频一区二区三区| 亚洲香蕉视频| 国产日韩欧美不卡在线| 在线视频日韩| 亚洲图片欧洲图片av| 欧美极品影院| 亚洲人成在线观看网站高清| 久久免费视频一区| 久久精品国产亚洲5555| 国产精品午夜在线| 亚洲一级一区| 亚洲欧美三级伦理| 欧美性大战xxxxx久久久| 亚洲乱码国产乱码精品精98午夜| 亚洲人成欧美中文字幕| 老司机免费视频久久| 99在线热播精品免费| 9l国产精品久久久久麻豆| 欧美国产亚洲另类动漫| 亚洲国产清纯| 日韩视频在线观看免费| 欧美精品成人一区二区在线观看| 国产精品99久久不卡二区| 久久五月激情| 亚洲电影在线| 男人的天堂成人在线| 亚洲黄网站在线观看| 99re在线精品| 国内自拍一区| 欧美成人午夜激情在线| 日韩一区二区精品| 噜噜噜久久亚洲精品国产品小说| 亚洲高清在线播放| 蜜乳av另类精品一区二区| 亚洲国产精品一区| 久久久国产亚洲精品| 在线精品观看| 国产欧美日韩综合精品二区| 久久aⅴ国产欧美74aaa| 欧美激情亚洲一区| 久久精品日韩一区二区三区| 中文av一区特黄| 亚洲精品一区久久久久久| 欧美日韩综合| 欧美一区视频| 亚洲国产精品一区二区尤物区| 久久激五月天综合精品| 亚洲一区二区黄色| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲黄色精品| 国产精品v欧美精品v日韩| 欧美不卡在线视频| 久久亚裔精品欧美| 久久精品亚洲乱码伦伦中文| 亚洲国产精品福利| 欧美国产第一页| 亚洲综合色婷婷| 伊人激情综合| 狠狠久久亚洲欧美专区| 国产一区二区三区奇米久涩| 国产欧美日韩视频| 国产精品一区二区在线| 欧美aaaaaaaa牛牛影院| 巨胸喷奶水www久久久免费动漫| 久久精品日韩欧美| 久久精品夜夜夜夜久久| 久久久国产视频91| 久久综合成人精品亚洲另类欧美| 久久久久国产精品厨房| 中文亚洲视频在线| 中国亚洲黄色| 亚洲欧美日韩在线一区| 亚洲精品永久免费| 日韩视频永久免费| 亚洲视频一二| 午夜视频在线观看一区二区| 亚洲精品资源美女情侣酒店| 日韩视频免费在线观看| 99日韩精品| 亚洲女女做受ⅹxx高潮| 日韩午夜激情av| 一区二区日韩精品| 亚洲人成免费| 一本大道久久精品懂色aⅴ | 国产伦精品一区二区三区在线观看 | 欧美在线视频不卡| 亚洲手机视频| 欧美亚洲综合网| 亚洲欧美春色| 亚洲一区二区三区乱码aⅴ| 亚洲欧美国产视频| 久久久久久综合| 久久精品91| 欧美第一黄网免费网站| 亚洲精选久久| 欧美一区二区三区四区在线| 美女主播精品视频一二三四| 欧美激情综合网| 国产麻豆精品theporn| 在线看一区二区| 亚洲午夜电影| 久久综合久久美利坚合众国| 亚洲黄色在线看| 亚洲欧美另类在线| 欧美国产精品人人做人人爱| 国产精品爱啪在线线免费观看| 国产一区二区三区直播精品电影| 亚洲精品久久久蜜桃| 久久国产精品一区二区| 亚洲国产黄色片| 91久久线看在观草草青青| 亚洲男人av电影| 欧美国产日产韩国视频| 国产欧美日韩在线观看| 一本久久a久久精品亚洲| 老鸭窝91久久精品色噜噜导演| 亚洲免费成人av电影| 久久男人资源视频| 国产精品丝袜久久久久久app| 亚洲欧洲精品一区二区精品久久久| 亚洲欧美国内爽妇网| 亚洲激情国产| 久久久久久国产精品mv| 国产精品美女久久| 韩国福利一区| 亚洲欧美另类中文字幕| 亚洲国产精品成人va在线观看| 午夜日韩电影| 国产精品成人一区二区网站软件| 国产精品一区在线观看你懂的| 亚洲福利一区| 久久久国产精品一区| 亚洲夜间福利| 欧美日韩精品一区视频| 国产麻豆午夜三级精品| 亚洲精一区二区三区| 欧美成人亚洲成人日韩成人| 欧美夜福利tv在线| 国产精品一区免费在线观看| 亚洲一卡二卡三卡四卡五卡| 亚洲激情网址| 欧美插天视频在线播放| 亚洲国产精品精华液2区45| 久久亚洲色图| 久久成人综合视频| 欧美日韩三级| 激情成人亚洲| 在线亚洲精品| 裸体女人亚洲精品一区| 久久xxxx精品视频| 国产欧美一区视频| 久久精品国产清高在天天线| 亚洲一区二区三区在线看| 久久艳片www.17c.com| 精品1区2区| 六月婷婷久久| 鲁鲁狠狠狠7777一区二区| 亚洲第一偷拍| 欧美激情1区2区3区| 蜜臀av性久久久久蜜臀aⅴ| 亚洲国产三级网| 亚洲激情在线| 欧美日韩午夜| 亚洲欧美一区二区精品久久久| 中文一区二区| 国产一级揄自揄精品视频| 久久影院亚洲| 免费视频久久| 中文一区在线| 亚洲免费影视| 黄色成人片子| 亚洲国产精品va在线看黑人| 欧美激情五月| 亚洲欧美在线免费| 欧美一区二区在线免费观看 | 香蕉久久夜色| 欧美影院一区| 亚洲日本欧美日韩高观看| 亚洲乱码国产乱码精品精可以看 | 夜久久久久久| 亚洲午夜视频在线| 一区二区在线观看av| 亚洲国产视频a| 国产精品久久久久影院亚瑟| 久久日韩精品| 欧美人与性禽动交情品| 亚洲黄色高清| 一区二区欧美视频| 韩国亚洲精品| 亚洲精品小视频| 国内精品久久久久久久影视麻豆 | 亚洲电影在线| 国产精品毛片va一区二区三区| 久久久久国色av免费看影院| 欧美成va人片在线观看|