インテリジェントポインタ実装


インテリジェントポインタ実装
  • 概要スマートポインタは、スマートポインタオブジェクトが通常のポインタタイプと同じ操作を持つように、通常のポインタをカプセル化するクラスです.オブジェクトをコピーするときに、コピーと元のオブジェクトが同じストレージ領域を指し、コピーまたは元のオブジェクトによって指定された値を変更すると、別のオブジェクトによってアクセスされる値も変更されます.スマートポインタはメモリを自動的に管理し、ポインタが垂れ下がることを避けることができます.C/C++言語では、作成対象がメモリ割り当てであり、使用後にメモリを解放する必要があり、メモリが正しく動作しないとメモリが漏洩する可能性があります.スマートポインタはこの問題を解決し、メモリを管理することができます.
  • 参照カウント参照カウントは、削除するメモリに他のポインタが存在するかどうかをポインタに知らせ、存在する場合はメモリを削除せず、存在しない場合は削除することで、サスペンションポインタの存在を回避することができる.参照カウントの目的:1)スタック内のオブジェクトを追跡するプロセスを簡略化します.オブジェクトの所有権を追跡し、オブジェクトを自動的に破棄できます.単純なごみ回収システムとして機能します.2)メモリを節約し、プログラムの運行効率を高める.多くのオブジェクトが同じ値を持っている場合、この値を共有し、複数のコピーをコピーして保存することを回避し、メモリを節約します.
  • インテリジェントポインタの実装は、補助クラスとハンドルクラスの2つのポリシーを使用して実装することができる.≪補助クラスの実装方法|Assistant Class Enforcement Method|emdw≫:ベース・オブジェクト・クラスを定義し、補助クラスを定義して実装します.補助クラスのすべてのメンバーはプライベートであり、一般ユーザーに使用されないようにします.スマートポインタを使用するには、スマートポインタクラスを補助クラスの友元として宣言する必要があります.セカンダリ・クラスには、カウントcountとベース・オブジェクト・ポインタの2つのデータ・メンバーが主に含まれます.リファレンスカウントは、スマートポインタを実現するための一般的な方法です.インテリジェントポインタは、1つのカウンタをクラスが指すオブジェクトに関連付け、参照カウントは、同じポインタを共有するクラスオブジェクトが何個あるかを追跡します.具体的な方法:1)クラスの新しいオブジェクトを作成すると、ポインタを初期化し、参照カウントを1に設定します.2)オブジェクトが別のオブジェクトのコピーである場合、コピーコンストラクタはコピーポインタをコピーし、ポインタに対応する参照数を増やす(プラス1).3)割り当てオペレータを使用して1つのオブジェクトに割り当てを行う場合は、左オペランドのポインタの参照カウントを1(1を減らすのはポインタが別の場所を指しているため)減らし、1を減らすと参照カウントが0になるとポインタが指すオブジェクトメモリを解放します.次に、右オペランドが指すオブジェクトの参照数を増やします(オペランドがオブジェクトを指すため、右オペランドがオブジェクトを指すためです).4)構造関数を呼び出すと、構造関数はまず参照カウントを1に減らし、0に減らすとdeleteオブジェクトになります.具体的には、
    #include <iostream>
    using namespace std;
    //        
    class Point
    {
        private:
            int x, y;
        public:
            Point(int xVal = 0, int yVal = 0): x(xVal), y(yVal) { }
            int getX() const
            {
                return x;
            }
            int getY() const 
            {
                return y;
            }
            void setX(int xVal)
            {
                x = xVal;
            }
            void setY(int yVal)
            {
                y = yVal;
            }
    }; 
    
    //    
    class U_Ptr
    {
        private:
            int count;
            Point *p;
    
            friend class SmartPtr;
            U_Ptr(Point *ptr): p(ptr), count(1) { }
            ~U_Ptr() { delete p; }
    }; 
    
    class SmartPtr
    {
        private:
            U_Ptr *rp;
        public:
            SmartPtr(Point *ptr): rp(new U_Ptr(ptr)){ }
            SmartPtr(const SmartPtr &sp): rp(sp.rp)
            {
                ++rp->count;
            }
            SmartPtr& operator= (const SmartPtr& rhs)
            {
                ++rhs.rp->count;
                if (--rp->count == 0)
                    delete rp;
                rp = rhs.rp;
                return *this;
            }
            ~SmartPtr()
            {
                if (--rp->count == 0)
                    delete rp;
                else
                    cout << "   " << rp->count << "         " << endl; 
            }
            Point& operator *()   //   *   
            {
                return *(rp->p);
            } 
            Point* operator ->()  //   ->   
            {
                return rp->p;
            } 
    };
    
    int main()
    {
        //            
        Point *pa = new Point(10, 20);
        //            ,          pa
        //                ,       
        {
            SmartPtr sptr1(pa);               //     count = 1 
            cout << sptr1->getX() << endl;
            {
                SmartPtr sptr2(sptr1);        //     count = 2 
                {
                    SmartPtr sptr3 = sptr1;   //     count = 3 
                }
                //   count = 2; 
            }
            //   count = 1; 
        } 
        //   count = 0;pa   delete  
        cout << pa->getX() << endl;
        return 0;
    }
    
    テンプレートによる
    #include <iostream>
    using namespace std;
    //              
    template <typename T> class SmartPtr;
    
    //    
    template <typename T> class U_Ptr
    {
        //          private,            。 
        private:
            T *p;           //       
            int count;      //      
            friend class SmartPtr<T>;           //           ,                 
            U_Ptr(T *ptr):p(ptr),count(1) { }   //                 
            ~U_Ptr() { delete p; }              //      
    };
    //      
    template <typename T> class SmartPtr
    {
        private:
            U_Ptr<T> *rp;   //          
        public:
            SmartPtr(T *ptr):rp(new U_Ptr<T>(ptr)) { }   //      
            SmartPtr(const SmartPtr<T> &sp):rp(sp.rp)    //        
            { 
                ++rp->count;
            } 
            SmartPtr& operator = (const SmartPtr<T> &rhs)//         
            {
                ++rhs.rp->count;       //           1 
                if (--rp.count == 0)   //           1,        
                    delete rp;
                rp = rhs.rp;
                return *this; 
            }
            T& operator *()            //   *    
            {
                return *(rp->p);
            }
            T* operator ->()           //   ->   
            {
                return rp->p;
            } 
            ~SmartPtr()                //      
            {
                if (--rp->count == 0)  //        0 ,         ,         
                    delete rp;
                else
                    cout << "   " << rp->count << "         " << endl; 
            }
    }; 
    int main()
    {
        int *i = new int(2);
        {
            SmartPtr<int> ptr1(i);
            {
                SmartPtr<int> ptr2(ptr1);
                {
                    SmartPtr<int> ptr3 = ptr2;
                    cout << *ptr1 << endl;
                    *ptr1 = 20;
                    cout << *ptr2 << endl;
                } 
            }
        }
        return 0;
    }
    
  • を実現する.
  • 参考文献http://mp.weixin.qq.com/s?__biz=MzAxNDI5NzEzNg==&mid=2651156666&idx=1&sn=4109903d526468f5913922d2f06e5a1a&scene=23&srcid=0528aIzOIN05Z0MQKuw7HrwJ#rd