• <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>
            OnTheWay2012
            埋葬昨天的我,迎來重生的我!
            posts - 15,  comments - 89,  trackbacks - 0
                    很久以前就對基于引用計數(shù)的指針指針很感興趣,今天突然又一次想到這個問題,所以就寫了一個基于引用技術(shù)的智能指針。該智能指針的具體實現(xiàn)方式如下:
              1#include <iostream>
              2#include <numeric>
              3#include <algorithm>
              4#include <map>
              5#include <assert.h>
              6
              8
              9using namespace std;
             10
             11template<typename T>
             12class SmartPointByRefCount
             13{
             14public:
             15    SmartPointByRefCount(T* pT) : m_pT(pT)
             16    {
             17        SmartPointByRefCount::AddRefCount((unsigned int)m_pT);
             18    }

             19
             20    SmartPointByRefCount(const SmartPointByRefCount& ref)
             21    {
             22        SmartPointByRefCount::AddRefCount((unsigned int)(ref.m_pT));
             23        m_pT = ref.m_pT;
             24    }

             25
             26    SmartPointByRefCount& operator=(const SmartPointByRefCount& ref)
             27    {
             28        if (this != &ref)
             29        {
             30            SmartPointByRefCount::AddRefCount(ref.m_pT);
             31            m_pT = ref.m_pT;
             32        }

             33
             34        return *this;
             35    }

             36
             37    ~SmartPointByRefCount()
             38    {
             39        if (SmartPointByRefCount::IsShouldDelete((unsigned int)m_pT))
             40        {
             41            SmartPointByRefCount::DelRefCount((unsigned int)m_pT);
             42            delete m_pT;
             43        }

             44        else
             45        {
             46            SmartPointByRefCount::RedRefCount((unsigned int)m_pT);
             47        }

             48    }

             49
             50    T* operator->()
             51    {
             52        return m_pT;
             53    }

             54
             55    T& operator*()
             56    {
             57        return *m_pT;
             58    }

             59
             60private:
             61    T *m_pT;
             62
             63private:
             64    static std::map<unsigned int, unsigned int> m_mapUseCount;
             65
             66public:
             67    static bool IsShouldDelete(unsigned int);
             68    static void AddRefCount(unsigned int);
             69    static void RedRefCount(unsigned int);
             70    static void DelRefCount(unsigned int);
             71}
            ;
             72
             73
             74template<typename T>  std::map<unsigned int, unsigned int> SmartPointByRefCount<T>::m_mapUseCount;
             75
             76template<typename T>  
             77bool SmartPointByRefCount<T>::IsShouldDelete(unsigned int nPointer)
             78{
             79    std::map<unsigned int, unsigned int>::const_iterator it = m_mapUseCount.find(nPointer);
             80    if (it != m_mapUseCount.end())
             81    {
             82        return ( 1 == it->second );
             83    }

             84    else
             85    {
             86        assert(false);
             87        return false;
             88    }

             89}

             90
             91template<typename T>  
             92void SmartPointByRefCount<T>::AddRefCount(unsigned int nPointer)
             93{
             94    std::map<unsigned int, unsigned int>::iterator it = m_mapUseCount.find(nPointer);
             95    if (it != m_mapUseCount.end())
             96    {
             97        (it->second)++;
             98    }

             99    else
            100    {
            101        m_mapUseCount[nPointer] = 1;
            102    }

            103}

            104
            105template<typename T>  
            106void SmartPointByRefCount<T>::RedRefCount(unsigned int nPointer)
            107{
            108    std::map<unsigned int, unsigned int>::iterator it = m_mapUseCount.find(nPointer);
            109    if (it != m_mapUseCount.end() && 1 < it->second)
            110    {
            111        (it->second)--;
            112    }

            113    else
            114    {
            115        assert(false);
            116    }

            117}

            118
            119template<typename T>  
            120void SmartPointByRefCount<T>::DelRefCount(unsigned int nPointer)
            121{
            122    std::map<unsigned int, unsigned int>::iterator it = m_mapUseCount.find(nPointer);
            123    if (it != m_mapUseCount.end())
            124    {
            125        m_mapUseCount.erase(it);
            126    }

            127    else
            128    {
            129        assert(false);
            130    }

            131}
                    以下是測試代碼,該智能指針能夠完全通過這些測試代碼。
             1SmartPointByRefCount<int> TestSPR(SmartPointByRefCount<int> dd)
             2{
             3    *dd = 4;
             4    return dd;
             5}

             6
             7
             8int main(int argc, char *argv)
             9{
            10    SmartPointByRefCount<int> spb1(new int(0));
            11    SmartPointByRefCount<int> spb2 = TestSPR(spb1);
            12    *spb1 = 2;
            13
            14    
            15    {
            16        SmartPointByRefCount<int> spb3(spb2);
            17        SmartPointByRefCount<int> spb4 = TestSPR(spb3);
            18    }

            19
            20    return 0;
            21}

                    寫完這個智能指針之后我在網(wǎng)上找了找其他人寫的智能指針,發(fā)現(xiàn)智能指針有兩種典型實現(xiàn)方式:侵入式、非侵入式,而我的實現(xiàn)方式是非侵入式的。以下兩篇文章是從網(wǎng)上引用的,從這兩篇文章中發(fā)現(xiàn)了一些問題,也學(xué)到了一些知識。以下引用內(nèi)容的所有版權(quán)歸原作者所有。

            第一篇:
                         一種自適應(yīng)的引用計數(shù)智能指針的實現(xiàn)

            0 引言
                    自行管理內(nèi)存是C ++ 語言的一個重要特征, 它為開發(fā)人員充分、靈活利用內(nèi)存空間提供了方 便,但同時也負(fù)擔(dān)了大量內(nèi)存的請求、釋放工作.
             程序的邏輯錯誤以及不確定的異常引發(fā),通常會由于內(nèi)存未釋放而造成系統(tǒng)的內(nèi)存泄漏. 實際工 作證明,內(nèi)存泄漏是最主要的C + + 程序Bug 之 一,由程序進(jìn)行自動內(nèi)存管理可有效地避免內(nèi)存 泄漏,這也是提高C + + 程序質(zhì)量的重要途經(jīng)之 一.
            自動內(nèi)存管理通常的方式是引入垃圾回收 (Garbage Collection) 機(jī)制. 垃圾回收作為動態(tài)語言 的特征之一早已存在于多種程序設(shè)計語言中,如 Java、Python 等. 遺憾的是最新的C ++ 標(biāo)準(zhǔn)并沒有將其引入,同時,由于C ++ 語言是強(qiáng)類型的靜態(tài)語言,通過程序來模擬垃圾回收機(jī)制非常困難,且功能有限. 避開垃圾回收,通過運用C ++ 語言的運算符重載和范型機(jī)制,在C ++ 社區(qū)產(chǎn)生了稱為智能指針(Smart Pointer) 的內(nèi)存工具. 所謂智能指針,實際上是一種類模板,當(dāng)其實例化后包含有指向動態(tài)分配內(nèi)存的指針,它通過重載* 、->運算符來模擬指針的行為,同時在適當(dāng)?shù)臅r候釋放內(nèi)存,以達(dá)到自動內(nèi)存管理的目的,其定義通常為template < typename T > class Smart Ptr. 現(xiàn)在,智能指針在C ++ 應(yīng)用開發(fā)中大量使用, 已經(jīng)成為C ++ 標(biāo)準(zhǔn)的工具之一.

            1   智能指針的一般實現(xiàn)和使用
             通常,智能指針按使用的策略分為兩類:一類是面向控制資源的所有權(quán)的智能指針,這類智能指針保證資源只被一個確定的對象使用,任何智能指針的拷貝或傳遞均會發(fā)生所有權(quán)的轉(zhuǎn)換,如標(biāo)準(zhǔn)庫提供的std : :auto ptr[1 ] ;另一類是面向資源共享的智能指針,這類智能指針內(nèi)部通常存在使用資源的記數(shù)器,稱為引用計數(shù),它保證引用計數(shù)為0 時(即不再有對象使用資源) 釋放資源, 如Boost 庫的boost : :shared ptr[2 ] . 智能指針能很好的完成內(nèi)存自動釋放,而它
             的使用與普通指針非常類似:
             {
                ??
                //定義int 的智能指針si
                   boost : :shared ptr < int > si = new int (1) ;
                  //直接使用si
                  std::cout<<*si<<std : :endl ;
                  //定義string 的智能指針st
                  boost::shared-ptr<std::string > st = new std::string(″Foo″) ;
                  //通過- > 運算符訪問string 的成員函數(shù)
                  st->clear () ;
                  //qt 和st 訪問的是同一資源
                  boost : :shared ptr < std : :string > qt = st ;
                  qt - > append(″Bar″) ;
                   ??
                   //si st 中的指針將自動釋放
             }

             2   引用計數(shù)的實現(xiàn)
                    資源共享型的智能指針引用計數(shù)的設(shè)計,一般分侵入式與非侵入式兩種. 侵入式引用計數(shù),將計數(shù)器作為包含對象的一部分,該方法效率比較 高,但要求包含類型總是繼承自一個計數(shù)對象;非侵入式引用計數(shù),計數(shù)器通過動態(tài)內(nèi)存分配獲得,任何的對象均可作為智能指針的范型參數(shù),但小內(nèi)存的new 操作會降低智能指針的效率. 關(guān)于效率和靈活的平衡,在智能指針的設(shè)計中是不能完成的,只有把這個問題交給智能指針的使用者. 但通過模板元編程以及模板偏特化,我們可以為使用者提供自動識別包含類型的智能指針[3 ] . 通過模板元編程可在程序的編譯期間判斷一個類型是否繼承自計數(shù)對象,如果是則采用侵入式,否則采用非侵入式.侵入式的引用計數(shù)應(yīng)繼承的基類:
               class IntrusiveRefCount
               {
               //操作引用計數(shù)成員函數(shù)
               ??
               protected :
                 int refCount ;PPP< 引用計數(shù)
              } ;
              通過不同的方式實現(xiàn)智能指針,模板參數(shù)IntrRefCount 缺省為True ,即采用侵入式:
              template < typename T,bool IntrRefCount >
              class SmartPtrImp
              {
                //重載賦值運算符.
                 //通過調(diào)用T的成員函數(shù)DecRef()和IncRef ( ) 來改變引用值
                    SmartPtrImp &operator = (const SmartPtrImp &sptr)
                    {
                      //釋放當(dāng)前資源
                      if (pointee ! = 0 &&pointee - > DecRef ( ) == 0)
                         delete pointee ;
                      pointee = sptr.pointee ;
                      if (pointee ! = 0)
                        pointee->IncRef() ;
                      return *this ;
                     }
                     //拷貝構(gòu)造函數(shù). 同樣有引用值的操作
                     SmartPtrImp (const SmartPtrImp &sptr) ;
             protected :
                         T *pointee ;///對象指針
                };
               采用模板偏特化參數(shù)IntrRefCount ( 特化為false) ,此類模板采用非侵入式模式:
               template < typename T>
               class SmartPtrImp < T,false >
               {
                 //重載賦值運算符.
               //直接new int (0) 來獲取記數(shù)器
                       SmartPtrImp &operator = (T* ptr)
                      {
                               if (pointee ! = 0)
                               {
                                         if (--(*refCountPtr ) == 0)
                                                delete pointee ;
                                       else
                                       //失去了對原對象的控制,原對象的引用計數(shù)也要放棄
                                           refCountPtr = new int (0) ;
                                 }
                              pointee = ptr ;
                              if (pointee ! = 0)
                                      ++refCountPtr ;
                      return *this ;
             }
                     //拷貝構(gòu)造函數(shù). 同樣有引用值的操作
                     SmartPtrImp (const SmartPtrImp &sptr) ;
              protected :
                     T *pointee ;///對象指針
                    int *refCountPtr;///引用計數(shù)
             } ;
             
            3        智能指針的實現(xiàn)
                    現(xiàn)在我們需要一個算法判斷一個類是否是另一個類的子類的范型算法[4 ] ,實現(xiàn)如下:
                    //如果沒有看過陳偉柱翻譯的《C++ Template》的話下面的代碼可能很難看懂,如果看不懂的話,不妨找這本書看一下
                     template < typename D ,typename B >
                     struct IsDerivedFrom
                     {
                             class No {} ;
                             class Yes {No no[2 ] ;} ;
                          static Yes Test (B*) ;
                       static No Test ( ?) ;
                          enum {Is = sizeof (Test ( static cast <D*> (0) ) ) = = sizeof(Yes) } ;
                     } ;
                     如果類型D 是B 的子類IsDerivedFrom < D ,B>::Is 的值就為1.
                     有了如上工具,我們就可以將智能指針的實現(xiàn)拼接起來:
                       template < typename T>
                       class SmartPtr :
                    public SmartPtrImp < T, IsDerivedFrom < T, IntrusiveRefCount>::Is == 1 >
                       {
                      typedef SmartPtrImp < T, IsDerivedFrom < T, IntrusiveRefCount>::Is == 1, Deletor < T > > ParentCls ;
                    public :
                     SmartPtr () :ParentCls () {}
                  explicit SmartPtr (T &t) :ParentCls (t) {}
                      explicit SmartPtr (T*t) :ParentCls (t) {}
                   SmartPtr (const SmartPtr &sptr) :ParentCls (sptr) {}
                 }

                                      
                    從以上的說明上看,這篇論文只有一點有價值的——講明白了智能指針的兩種實現(xiàn)方式,侵入式和非侵入式。至于這篇自適應(yīng)的說法,個人感覺在編碼的時候根本不會用到。其中紅色的文字是我添加的。


            第二篇:

                    指針 是C++中不得不談的一個話題,或許我還不是很能熟練的掌握指針以及我所要討論的引用計數(shù)型指針的全部,但是還是有那么些迫不及待想要表達(dá)一下。
                    指針pointer 是 資源泄漏 resource leak 的根源(當(dāng)然可能還有其他一些什么東西,在我的映像中 異常 仿佛也會造成資源泄漏)最簡單的一個資源泄漏的例子就是new和delete這樣的動態(tài)內(nèi)存分配算子沒有正確使用造成的:
            struct A
            {
            A()  { printf("A Constructor!"); }
            ~A() { printf("A Destructor!"); }
            };

            void area()
            {
            A *p = new A();
            }
            執(zhí)行完 area() 后,自然是只有A構(gòu)造的消息,而A的析構(gòu)卻不見影蹤。這里我們在離開了area作用域后,我們就無法對p所指向之資源進(jìn)行操作,A的實例就會被懸掛在內(nèi)存的某處得不到清理。一個形象點的比方就像人類發(fā)送的宇宙衛(wèi)星失去了動力以及和地球的聯(lián)系,無法收回,就變成了宇宙垃圾~。
            然而利用對象來管理資源是一個很好的辦法,因為對象的實例本身在脫離作用域后會自動清理,就像這樣

            class  A_holder
            {
            public:
            expilict A_holder(A* p = NULL):ptr(p) {}

            ~A_holder()
            {
            if (ptr)
            delete ptr;
            }
            private:
            A* ptr;
            };
            如此,我們在area里面把資源的管理權(quán)力交給A_holder,就像下面這樣
            void area()
            {
            A_holder ah(new A);
            }
            這樣,ah在離開area后會自動調(diào)用其析構(gòu)函數(shù),就達(dá)到了自動管理該資源的目的。
            利用C++的類的實例離開作用域會自動調(diào)用其析構(gòu)函數(shù)的機(jī)制,可以比較方便的管理資源,但是在使用普通指針的情況下會存在多個指針指向同一對象的情況。
            void multi_point()
            {
            int a;
            int *p1,*p2;

            p1 = &a;
            p2 = &a;
            }
            實際的指針指向情況應(yīng)該是這樣 p1 –>? a ?<- p2。
            這里就出現(xiàn)了一個問題,我們想取消p1的時候可能會出現(xiàn)兩種語義:
            1、將p1和其指向的對象一起刪除,這樣p2也就不可以繼續(xù)對a進(jìn)行使用。但是往往p2的使用者不會知道a已經(jīng)刪除,則出現(xiàn)了錯誤。
            2、將p1與其指向的對象解除關(guān)系,這樣p2還可以對a進(jìn)行使用。
            對于普通的delete操作,實現(xiàn)的是第一種情況,這樣通過p2對a進(jìn)行訪問必然會造成致命的錯誤。
            在實現(xiàn)holder類的時候應(yīng)該也考慮到第二種情況,如果有另外一個holder也指向這個資源,其中一個holder銷毀,另外一個holder還可能會使用到它們共同指向的那個資源。于是,holder的作用就不僅僅是單單的持有和施放資源,還應(yīng)該處理有多少個對其hold資源的引用(即引用計數(shù)),并且在引用計數(shù)降為0時真正的銷毀資源實體。
            如此,一個行為類似指針(有->,*操作符)的智能指針出現(xiàn),它管理賦予其資源的引用計數(shù),也管理該資源的生死存亡。
            一個簡單的Reference Count Smart Pointer的實現(xiàn)如下:
            #ifndef COUNTED_PTR_HPP
            #define COUNTED_PTR_HPP
            /*class for counted reference semantics
            *-deletes the object to which it refers when the last CountedPtr
            * that refers to it is destroyed
            */
            template <class T>
            class CountedPtr
            {
            private:
             T* ptr;        // pointer to the value
             long* count;   // shared number of owners
            public:
             //initialize pointer with existing pointer
             //-requires that the pointer p is a return value of new
             explicit CountedPtr (T* p=0)
              : ptr(p), count(new long(1)) {}
             //copy pointer (one more owner)
             CountedPtr (const CountedPtr<T>& p) throw()
              : ptr(p.ptr), count(p.count)
             {
              ++*count;
             }
             //destructor (delete value if this was the last owner)
             ~CountedPtr () throw()
             {
              dispose();
             }
             //assignment (unshare old and share new value)
             CountedPtr<T>& operator= (const CountedPtr<T>& p) throw() {
              if (this != &p) {
               dispose();
               ptr = p.ptr;
               count = p.count;
               ++*count;
              }
              return *this;
             }
             //access the value to which the pointer refers
             T& operator*() const throw() {
              return *ptr;
             }
             T* operator->() const throw() {
              return ptr;
             }
            private:
             void dispose() {
              if (--*count == 0) {
               delete count;
               delete ptr;
              }
             }
            };
            #endif /*COUNTED_PTR_HPP*/
            由此,一個新的問題出現(xiàn)了!循環(huán)引用!
            這樣的一個引用計數(shù)型智能指針目的是為了防止資源泄漏,但是只需要一個很小巧的代碼就可以讓這樣的初衷化為烏有……。
            class A
            {
            public:
             A() {cout<<"A CON"<<endl;}
             ~A() {cout<<"A DES"<<endl;}

             void hold(CountedPtr<A> ptr)
             {
              m_ptr = ptr;
             }
            private:
             CountedPtr<A> m_ptr;
            };

            void self_cir_area()
            {
             CountedPtr<A> pA(new A());
             pA->hold(pA);
            }

            可以看見,一個對象A中有一個引用計數(shù)型智能指針,這樣的設(shè)計可能會很常見(指向自身類型的結(jié)構(gòu)體——鏈表)
            但是,當(dāng)自身循環(huán)引用發(fā)生的時候會怎么樣呢? 下面就來看看這么兩句代碼
            CountedPtr<A> pA(new A());
            這里我們新建一個資源,并且把這個資源的管理權(quán)移交給pA這個引用計數(shù)型智能指針對象管理。如此,pA中的引用計數(shù)被初始化為1。
            pA->hold(pA);
            這里,我們把pA對象傳入給實例化的A對象中的引用計數(shù)型智能指針m_ptr,m_ptr執(zhí)行這樣的一個成員函數(shù):   
            //assignment (unshare old and share new value)
            CountedPtr<T>& operator= (const CountedPtr<T>& p) throw() {
             if (this != &p) {
              dispose();
              ptr = p.ptr;
              count = p.count;
              ++*count;
             }
             return *this;
            }
            因為這里很明顯不是自身賦值,A中的m_ptr和pA不是同一個對象,所以進(jìn)入if結(jié)構(gòu)中調(diào)用下面的內(nèi)容。dispose是用作清理,因為m_ptr并沒有指向任何東西,所以第一個函數(shù)并沒有真正的意義。然后
            m_ptr.ptr = pA.ptr;
            m_ptr.count = pA.count;
            ++(*m_ptr.count);  //(*pA.count)也被++
            到此,pA的引用計數(shù)為2
            嗯,下面就pA這個對象理所當(dāng)然的離開了作用域,調(diào)用其析構(gòu)函數(shù):
            ~CountedPtr () throw() {
             dispose();
            }
            噢,是一個轉(zhuǎn)向,調(diào)用其private成員函數(shù)dispose():
            void dispose() {
             if (--*count == 0) {
              delete count;
              delete ptr;
             }
            }
            很簡單,將引用計數(shù)-1,由2變成1,不為0,所以if結(jié)構(gòu)內(nèi)的語句不被執(zhí)行。
            由此,我們又制造了一個完美的太空垃圾……
            這樣的循環(huán)引用問題應(yīng)該是在設(shè)計的過程中就應(yīng)該避免的,如果用UML語言描述
            A中持有一個 引用計數(shù)型智能指針 的語義就是 這個 持有關(guān)系 是需要在 A消失的時候所持有的對象也隨之消失(這正是智能指針的作用,在脫離作用域自動清除其持有的資源)。如此就構(gòu)成了 組合 關(guān)系。如果要表示 聚合 關(guān)系,即有 部分-整體 關(guān)系但是部分不隨整體的消失而消失,這就不是 智能指針 所表達(dá)的語義。
            還有可能遇見的循環(huán)引用就是 A1 持有 A2, A2 持有 A1 的情況……
            這樣A1,A2中對雙方的引用計數(shù)都是2,當(dāng)一方“銷毀”的時候,雙方的應(yīng)用計數(shù)都變?yōu)?,實際上并沒有銷毀任何東西,制造了兩個完美無暇的太空垃圾~
            這里又引發(fā)出一個問題,這樣的資源泄漏問題實際上還是由程序員自身引起的。
            C++之所以是一個很容易出錯的語言,很大一部分在于其資源的管理權(quán)力全權(quán)交給了程序員。這樣的權(quán)力到底是造福了程序員還是迷惑了程序員呢?
            這里我卻想起了蜘蛛俠中的一句名言: “一個人能力有多大,責(zé)任就有多大!”
            對C++中指針的指責(zé)不是一天兩天了,其易錯性無可厚非,但是它卻給了你其他語言無法給你的能力!這就是我的觀點,你能力有這么大,你就有責(zé)任來治理好這些資源。而非一再推卸責(zé)任。如果真的是要推卸責(zé)任,也就應(yīng)該去選擇其他那些剝奪你的能力而減少你的責(zé)任的語言,因為你有選擇權(quán)!就像說英語和中文一樣,并沒有哪個人在強(qiáng)迫你,不是么?熱愛C++是一種態(tài)度,對一個語言的利弊都了然于心,了解其可以做什么不可以做什么,怎樣才可以更好的使用它來做什么,才能更好的使用它。更何況,there are rarely things that are not possible in C++。

             

            在沒有看到這篇文章之前,我覺得智能指針能夠應(yīng)對所有情況,可是看過這篇文章讓我了解到智能指針在循環(huán)引用的情況下也會出現(xiàn)問題。

            另外,我還發(fā)現(xiàn)我的operator=函數(shù)有問題,具體的問題請參見上面兩篇文章的operator=函數(shù)。此外,本實現(xiàn)還有一些問題沒有考慮:線程安全,if(智能指針)等。
            天太晚了,所以就不排版了,請見諒!

            posted on 2010-12-17 22:43 OnTheWay 閱讀(2918) 評論(3)  編輯 收藏 引用 所屬分類: 個人感悟

            FeedBack:
            # re: 一種基于引用計數(shù)機(jī)制的智能指針實現(xiàn)[未登錄]
            2010-12-17 22:55 | hdqqq
            比較討厭這種引用計數(shù)指針的使用,一旦使用就意味這在所有的函數(shù)參數(shù)中必須使用指針引用或者值拷貝,一旦某些函數(shù)要求用裸指針,就可能引發(fā)問題。  回復(fù)  更多評論
              
            # re: 一種基于引用計數(shù)機(jī)制的智能指針實現(xiàn)
            2010-12-18 20:38 | Phuehvk
            Boost 里面有,在C++ TR1 里面也已經(jīng)有這種指針(就是來自Boost)  回復(fù)  更多評論
              
            # re: 一種基于引用計數(shù)機(jī)制的智能指針實現(xiàn)
            2010-12-21 19:49 | 叫我老王吧
            把A *p = new A();這句換成A p;不行嗎?  回復(fù)  更多評論
              

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            友情連接

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品久久久久国产A级| 久久久91精品国产一区二区三区| 久久这里只有精品首页| 色88久久久久高潮综合影院| 久久AAAA片一区二区| 久久综合狠狠综合久久激情 | 久久99精品久久久久久hb无码 | 久久99亚洲网美利坚合众国| 久久久久免费精品国产| 少妇熟女久久综合网色欲| 亚洲欧美一区二区三区久久| 亚洲伊人久久综合中文成人网 | 久久综合一区二区无码| 久久电影网| 亚洲美日韩Av中文字幕无码久久久妻妇 | 国内精品久久久久久久影视麻豆| 久久精品国产亚洲麻豆| 中文精品久久久久国产网址| 国产99久久久久久免费看| 久久99精品免费一区二区| 欧美日韩精品久久久久| 2020久久精品亚洲热综合一本| 久久亚洲AV成人无码| 亚洲精品国精品久久99热一| 久久免费的精品国产V∧| 久久精品国产亚洲AV电影 | 国产AV影片久久久久久| 少妇久久久久久被弄到高潮| 久久天天躁夜夜躁狠狠| 精品国产乱码久久久久久郑州公司| 久久99精品久久久久久动态图| 婷婷综合久久中文字幕| 欧美久久久久久精选9999| 久久久久亚洲av综合波多野结衣| 久久精品人人槡人妻人人玩AV| 久久免费国产精品一区二区| 开心久久婷婷综合中文字幕| 亚洲午夜久久久久久久久电影网| 久久国产精品成人免费| 亚洲欧美另类日本久久国产真实乱对白 | 亚洲AV日韩AV永久无码久久|