C++中智能指標的實現__C++

來源:互聯網
上載者:User

C++學習中遇到的問題,記錄之。使用的教材: 《C++ primer》。

智能指標。what。 how。
What ‘s the smartpointer and how to impletment it?

什麼是智能指標。
通過引用計數,自動管理動態分配的記憶體的生存期,避免記憶體流失或懸垂指標的方法。
應用情境:
如果類的一個成員是指向動態分配的記憶體塊的指標,在做複製控制的時候,我們有兩種方法:
1、複製指標指向的記憶體塊,為了避免記憶體流失,會在類的解構函式裡釋放記憶體。這樣為造成記憶體空間的浪費,copy操作也會帶來不必要的開銷。
2、只複製指標。但引入了新的問題:當通過一個副本對象的指標成員釋放了這個記憶體塊之後,其它指標就成了所謂的懸垂指標。

這裡引入智能指標,來解決2 中帶來的問題。


如何?智能指標。
為瞭解決這個問題,我們在方法2裡,加入引用計數的方法,來管理這個對象的記憶體釋放。
假設我們這裡需要管理的是一個int型指標ip指向的記憶體。如下圖:


通過U_ptr來將指標和一個引用計數綁定在一起,然後類HasPtr通過一個指向U_ptr的指標成員來間接訪問 ip 指向的記憶體。
(這裡應該限制,一個記憶體塊只對應一個U_ptr的對象)
U_ptr的引用計數 use 初始化為1.
所有對類HasPtr的對象的複製控制操作,都會修改U_ptr的引用計數。
每次對這個HasPtr對象的copy,都不copy 指標 ip 指向的記憶體塊,但對U_ptr的use加一。
每一個對象的解構函式中,都判斷use減一後是否為0,如果是,則銷毀U_ptr對象綁定的那個記憶體塊。

//C++ primer plus ...... chapter 8  page253#include <iostream>#include <string>#include <new>using namespace std;class U_Ptr{private:friend class HasPtr;int *ip;size_t use;U_Ptr(int *p):ip(p),use(1){ }
~U_Ptr() {cout << "U_Ptr destructor...free mem ip = " << ip << endl;delete ip; }};class HasPtr{public:HasPtr(const string &str, int *p):name(str),ptr(new U_Ptr(p)) {cout << name << "\tHasPtr do normal construct" << endl;}HasPtr(const string &str, const HasPtr &orig):name(str),ptr(orig.ptr) {cout << name << "\tHasPtr do copy construct" << endl;++ptr->use; }//some friend operatorsfriend std::ostream& operator<<(std::ostream& , const HasPtr &);HasPtr& operator=(const HasPtr &orig){cout << name << "\tHasPtr do assignment from "<< orig.name << endl;if(orig.ptr == this->ptr){cout << "They are the same one, do nothing" << endl;return *this;}++orig.ptr->use; if(--ptr->use == 0){cout << name << "\tdelete ptr "<< endl;delete ptr;}else {cout << name << "\tptr usecnt = " << ptr->use << endl;}ptr = orig.ptr;return *this;}~HasPtr(){--ptr->use;cout << name << "\tHasPtr destructor ... ptr usecnt = " << ptr->use << endl;if( ptr->use == 0 ){delete ptr; //here call U_Ptr's destructor}}//some apiint * get_ptr() const {return ptr->ip ;}int get_ptr_val() const { return *(ptr->ip) ;}void set_ptr(int *p) { ptr->ip = p ;}void set_ptr_val(int i) { *ptr->ip = i ;}private:string name;U_Ptr *ptr;};std::ostream& operator<<(std::ostream& os , const HasPtr &hp){os << hp.name <<"\tval = "<< hp.get_ptr_val() << "\taddr = "<< hp.get_ptr();return os;}//overloaded the operator "<<".int main(int argc, char const *argv[]){int *a = new int(123);cout << endl << "normal constructor" << endl;HasPtr cp1("cp1", a);cout << cp1 << endl;cout << endl << "copy constructor" << endl;HasPtr cp2("cp2",cp1);cp2.set_ptr_val(199);cout << cp2 << endl;cout << endl << "assignment operator " << endl;cp2 = cp1 ;cout << cp2 << endl;cout << endl << "more HasPtr to a" << endl;HasPtr cp3("cp3" , a);HasPtr cp4("cp4" , a);cout << cp3 << endl;cout << cp4 << endl;if(a!=NULL)cout << "a is still keep the mem, addr = " << *a << endl;elsecout << "a has been free mem" << endl;cout << endl << ".................exit from main" << endl;//delete(a); //do not need free mem herereturn 0;}


在linux下,使用g++編譯,運行結果:

normal constructorcp1HasPtr do normal constructcp1val = 123addr = 0x9f0d008copy constructorcp2HasPtr do copy constructcp2val = 199addr = 0x9f0d008assignment operator cp2HasPtr do assignment from cp1They are the same, do nothingcp2val = 199addr = 0x9f0d008more HasPtr to acp3HasPtr do normal constructcp4HasPtr do normal constructcp3val = 199addr = 0x9f0d008cp4val = 199addr = 0x9f0d008a is still keep the mem, addr = 199.................exit from maincp4HasPtr destructor ... ptr usecnt = 0U_Ptr destructor...free mem ip = 0x9f0d008cp3HasPtr destructor ... ptr usecnt = 0U_Ptr destructor...free mem ip = 0x9f0d008cp2HasPtr destructor ... ptr usecnt = 1cp1HasPtr destructor ... ptr usecnt = 0U_Ptr destructor...free mem ip = 0x9f0d008






相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.