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

隨筆 - 55  文章 - 15  trackbacks - 0
<2025年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用鏈接

留言簿

隨筆分類

隨筆檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

PS:本文為轉載。鏈接地址: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)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   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>
            国产日韩欧美中文在线播放| 国产亚洲欧美一区在线观看| 亚洲精品国产精品乱码不99| 蜜臀av性久久久久蜜臀aⅴ四虎| 久久成人免费| 尤物yw午夜国产精品视频明星| 久久躁狠狠躁夜夜爽| 久久成人一区| 亚洲精品五月天| 一区二区免费在线观看| 国产女主播一区| 欧美99在线视频观看| 免费亚洲婷婷| 亚洲欧美日韩国产综合在线| 亚洲欧美综合网| 亚洲国产人成综合网站| 亚洲精品小视频| 国产情人综合久久777777| 久久五月激情| 欧美另类在线播放| 久久精品免视看| 欧美激情aaaa| 久久精品日韩欧美| 欧美极品aⅴ影院| 欧美一区国产一区| 欧美国产日本在线| 久久久久久久久伊人| 欧美国产日韩在线观看| 香港久久久电影| 欧美福利电影在线观看| 午夜精品剧场| 欧美电影在线观看| 久久精品五月| 欧美日韩在线播| 女女同性精品视频| 国产日本亚洲高清| 日韩一区二区精品葵司在线| 永久555www成人免费| 亚洲一区二区三区涩| 亚洲国产欧美在线| 久久精品国产第一区二区三区最新章节| 亚洲免费播放| 久久青草福利网站| 欧美伊人久久久久久午夜久久久久 | 欧美日韩亚洲91| 蜜桃av一区| 黑人巨大精品欧美一区二区| 亚洲无毛电影| 亚洲色在线视频| 欧美精品久久一区二区| 欧美不卡在线| 激情久久久久久久| 午夜精品视频在线观看| 亚洲在线播放电影| 欧美日韩另类字幕中文| 亚洲国产一区二区精品专区| 国产一区二区三区免费不卡| 亚洲午夜激情网页| 亚洲一区二区在线看| 欧美精品在线一区| 亚洲黄一区二区| 亚洲精品久久久久久久久久久久久 | 99视频在线精品国自产拍免费观看| 亚洲国产成人精品女人久久久| 欧美一区二区三区四区在线| 性欧美videos另类喷潮| 国产精品一区二区三区乱码 | 老司机午夜精品视频在线观看| 国产精品亚洲欧美| 午夜精品福利在线观看| 久久精品二区三区| 国产欧美短视频| 香蕉久久精品日日躁夜夜躁| 久久九九99| 一区在线影院| 免费久久99精品国产自在现线 | 在线视频你懂得一区二区三区| 欧美激情第三页| 日韩网站在线观看| 亚洲欧美日韩精品久久久久| 国产精品无码专区在线观看| 午夜精品免费在线| 欧美xxx成人| 一本大道久久a久久综合婷婷| 欧美日韩视频免费播放| 亚洲一区二区三区在线观看视频| 久久精品99久久香蕉国产色戒 | 国产精品久久久久久久久久免费| 亚洲一区二区欧美| 久久综合99re88久久爱| 亚洲肉体裸体xxxx137| 国产精品成人国产乱一区| 亚洲一区二区三区三| 久久夜色精品国产噜噜av| 亚洲人成网站在线观看播放| 欧美日韩和欧美的一区二区| 亚洲午夜在线视频| 欧美成人中文| 亚洲无线一线二线三线区别av| 国产日韩精品在线观看| 久久综合久久综合久久| 一区二区免费看| 蜜臀av一级做a爰片久久| 在线视频日韩精品| 精东粉嫩av免费一区二区三区| 欧美黑人在线播放| 香蕉成人啪国产精品视频综合网| 欧美aa在线视频| 亚洲免费视频在线观看| 亚洲电影免费在线| 国产精品久久久久一区二区三区共| 欧美一区二区三区精品| 亚洲另类在线一区| 免费成人av| 久久激情综合| 亚洲一区日韩| 亚洲精品孕妇| 在线观看亚洲精品视频| 国产精品香蕉在线观看| 欧美经典一区二区三区| 久久久久久网址| 亚洲男女自偷自拍| 9l国产精品久久久久麻豆| 女女同性精品视频| 久久久xxx| 欧美在线视频一区二区| 亚洲午夜三级在线| 99re6这里只有精品视频在线观看| 国产综合激情| 国产精品网站在线播放| 欧美视频在线看| 欧美日韩国产电影| 欧美成人免费va影院高清| 久久午夜色播影院免费高清| 欧美一区91| 欧美一级视频精品观看| 亚洲调教视频在线观看| 日韩午夜剧场| 99视频精品在线| 亚洲精品欧美精品| 亚洲精品久久| 亚洲精品麻豆| 日韩亚洲欧美成人一区| 亚洲日本理论电影| 日韩一区二区精品| 一本色道久久综合亚洲精品不卡 | 亚洲欧美日韩综合一区| 亚洲一区二区在线免费观看视频| 一区二区三区精品在线| 一区二区日韩欧美| 亚洲免费网站| 久久成人av少妇免费| 久久久久99精品国产片| 久久久久久穴| 欧美国产日韩精品| 欧美特黄一级| 国产精品日韩欧美一区| 国产婷婷色一区二区三区| 激情成人在线视频| 亚洲精品欧美极品| 中文日韩在线视频| 午夜精品久久久久久久99黑人| 欧美一区二区三区视频在线| 久久国产视频网| 欧美福利视频| 日韩视频在线一区二区| 亚洲色图综合久久| 亚洲综合日韩| 久久亚洲精选| 欧美性天天影院| 极品少妇一区二区| 99视频+国产日韩欧美| 欧美在线高清| 亚洲电影第三页| 亚洲一区二区综合| 麻豆精品一区二区av白丝在线| 欧美日韩成人一区二区三区| 国产精品视频观看| 亚洲激情一区| 亚洲欧美日韩精品| 欧美激情免费观看| 亚洲影视在线| 免费影视亚洲| 国产无遮挡一区二区三区毛片日本| 亚洲春色另类小说| 午夜欧美不卡精品aaaaa| 亚洲成色精品| 欧美伊人久久| 欧美视频官网| 亚洲精品一区二区在线| 久久精品一区二区三区四区| 亚洲欧洲三级| 久久中文字幕一区| 国产精品毛片va一区二区三区 | 国内成人在线| 亚洲欧美日韩国产综合在线| 亚洲成在人线av| 久久精品国产99| 国产欧美日韩在线播放| 一区二区三区欧美日韩|