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

隨筆 - 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>
            国产精品videossex久久发布| 久久久免费观看视频| 亚洲精品中文字幕在线观看| 国模叶桐国产精品一区| 一区二区三区中文在线观看| 在线精品福利| 亚洲精品国产精品国自产在线| 日韩亚洲欧美成人| 亚洲欧美区自拍先锋| 久久高清福利视频| 欧美成人高清| 日韩午夜在线| 午夜精品久久久久| 免费在线观看一区二区| 欧美肉体xxxx裸体137大胆| 国产精品红桃| 在线播放日韩专区| 一区二区三区欧美在线| 久久精品一二三区| 最新国产成人av网站网址麻豆| 亚洲精品少妇| 久久超碰97人人做人人爱| 牛牛国产精品| 国产欧美精品va在线观看| 91久久精品一区二区别| 亚洲日本中文字幕| 欧美一区二区三区在线观看视频 | 99精品久久| 亚洲欧美激情视频在线观看一区二区三区 | 国产一区二区三区不卡在线观看| 在线看国产日韩| 中文久久乱码一区二区| 久久久久久亚洲精品中文字幕 | 欧美在线日韩精品| 欧美午夜理伦三级在线观看| 亚洲成在线观看| 欧美一级专区| 一区二区精品国产| 欧美国产日韩精品免费观看| 国产亚洲精品久久久| 亚洲性图久久| 亚洲日本成人| 免费国产自线拍一欧美视频| 国产视频精品网| 亚洲一级在线观看| 亚洲精品乱码久久久久久蜜桃91| 久久久国产精彩视频美女艺术照福利| 欧美午夜电影在线观看| 99国产精品自拍| 亚洲国产成人av| 久久久久欧美| 影音先锋日韩精品| 老司机午夜精品视频在线观看| 亚洲欧美日韩在线播放| 国产精品久久久999| 亚洲伊人观看| 亚洲小视频在线| 国产精品进线69影院| 亚洲一级免费视频| 在线亚洲精品| 国产农村妇女毛片精品久久莱园子 | 亚洲日本免费| 欧美日韩极品在线观看一区| 99精品久久免费看蜜臀剧情介绍| 亚洲国产电影| 欧美日韩一区高清| 先锋影音一区二区三区| 午夜精品久久久久久久男人的天堂 | 国产在线欧美日韩| 久久精品九九| 久久狠狠久久综合桃花| 国产日韩欧美综合在线| 久久免费黄色| 久久最新视频| 亚洲日本中文字幕免费在线不卡| 亚洲福利在线看| 欧美日韩高清在线播放| 亚洲一区二区精品在线| 亚洲欧美成人一区二区三区| 国产欧美日本一区视频| 老色鬼精品视频在线观看播放| 久久一区视频| 夜夜嗨av色综合久久久综合网| 亚洲精品中文字| 国产精品毛片大码女人 | 一区二区免费在线播放| 国产伦精品一区二区三区四区免费 | 亚洲国产欧美一区| 欧美四级在线| 久久久久久国产精品一区| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲日本成人| 亚洲一区国产视频| 亚洲电影专区| 亚洲一区二区三区在线播放| 在线观看欧美日本| 亚洲午夜一区二区| 亚洲区第一页| 欧美一区二区三区喷汁尤物| 亚洲精品免费网站| 欧美在线亚洲一区| 亚洲一区二区三区午夜| 久久综合久久美利坚合众国| 亚洲欧美日韩高清| 欧美激情导航| 老司机67194精品线观看| 国产精品爱久久久久久久| 免费视频一区二区三区在线观看| 欧美性色aⅴ视频一区日韩精品| 欧美高清视频一区二区| 国产欧美日韩综合| 99精品国产福利在线观看免费| 亚洲高清久久网| 欧美亚洲尤物久久| 亚洲一区二三| 欧美巨乳在线观看| 亚洲电影免费观看高清完整版在线| 国产精品日韩二区| 99综合在线| 一本高清dvd不卡在线观看| 久久免费视频一区| 久久久久久9| 国产三级欧美三级| 亚洲一区影音先锋| 亚洲欧美国产精品桃花| 欧美日韩中字| 欧美在线高清视频| 性欧美精品高清| 国产精品vvv| 亚洲视频狠狠| 亚洲视频免费在线| 欧美午夜影院| 一本久道久久综合狠狠爱| 99re热这里只有精品免费视频| 猫咪成人在线观看| 欧美激情第3页| 亚洲国产日韩欧美在线99| 久久这里只有精品视频首页| 另类国产ts人妖高潮视频| 黄色日韩网站| 美女日韩欧美| 亚洲日本欧美| 亚洲影院免费| 国产精品一区二区欧美| 性欧美长视频| 美日韩精品免费观看视频| 在线观看一区二区视频| 欧美77777| 一区二区免费在线观看| 欧美一区二区三区视频免费| 国产亚洲精品一区二555| 久久精品国产精品亚洲| 欧美国产日本在线| 一区二区三区四区五区视频| 欧美午夜一区二区福利视频| 午夜精品一区二区三区四区| 美女尤物久久精品| 一本色道久久综合亚洲精品按摩| 欧美三区美女| 欧美在线免费观看| 亚洲激情欧美| 欧美伊人久久久久久午夜久久久久 | 欧美午夜电影网| 亚洲你懂的在线视频| 麻豆成人综合网| 在线综合亚洲| 国精产品99永久一区一区| 欧美本精品男人aⅴ天堂| 一区二区三区视频观看| 麻豆精品91| 亚洲一区二区在线免费观看| 有码中文亚洲精品| 欧美性猛交xxxx乱大交退制版| 久久精品国产视频| 99精品久久久| 欧美激情aⅴ一区二区三区| 亚洲欧美国产三级| 亚洲美女电影在线| 国内精品99| 国产精品卡一卡二| 欧美搞黄网站| 午夜一区二区三视频在线观看| 亚洲国产欧美在线| 美女主播视频一区| 久久精品国产精品亚洲| 一区二区三区精品| 亚洲日韩视频| 激情五月婷婷综合| 国产麻豆综合| 欧美午夜片在线观看| 欧美国产日韩一区二区三区| 久久gogo国模啪啪人体图| 亚洲一区二区三区四区中文 | 久久久99精品免费观看不卡| 亚洲国产视频直播| 国内精品久久久| 国产精品国产成人国产三级| 免费不卡在线观看av| 久久精品123| 性久久久久久久久|