Une simple mise en œuvre de Pointeur Intelligent de la Classe

Dans le livre C++ Primer 13.5.1, mettre en place un Pointeur Intelligent de la Classe à l'aide d'un Utilisez-le Comte de Classe. Leur mise en œuvre est comme suit:

  • Utilisez-Le Comte De Classe

    //private class for use by HasPtr only
    class U_Ptr {
        friend class HasPtr;
        int *ip;
        size_t use;
        U_Ptr(int *p): ip(p), use(1) { }
        ~U_Ptr() { delete ip; }
    };
  • Pointeur Intelligent De La Classe

    /* 
       smart pointer class: takes ownership of the dynamically allocated
       object to which it is bound
    
       User code must dynamically allocate an object to initialize a HasPtr
       and must not delete that object; the HasPtr class will delete it
    */
    class HasPtr {
    public:
        //HasPtr owns the pointer; p must have been dynamically allocated
        HasPtr(int *p, int i)
            : ptr(new U_Ptr(p)), val(i) { }
    
        //copy members and increment the use count
        HasPtr(const HasPtr &orig)
            : ptr(orig.ptr), val(orig.val) { ++ptr->use; }
    
        HasPtr& operator=(const HasPtr&);
    
        //if use count goes to zero, delete the U_Ptr object
        ~HasPtr() { if (--ptr->use == 0) delete ptr; } 
    
        friend ostream& operator<<(ostream&, const HasPtr&);
        //copy control and constructors as before
    
        //accessors must change to fetch value from U_Ptr object
        int *get_ptr() const { return ptr->ip; } 
        int get_int() const { return val; }
    
        //change the appropriate data member
        void set_ptr(int *p) { ptr->ip = p; }
        void set_int(int i) { val = i; }
    
        //return or change the value pointed to, so ok for const objects
        //Note: *ptr->ip is equivalent to *(ptr->ip)
        int get_ptr_val() const { return *ptr->ip; } 
        void set_ptr_val(int i) { *ptr->ip = i; }
    private:
        U_Ptr *ptr;        //points to use-counted U_Ptr class
        int val;
    };

Me demande: je suis curieux de savoir pourquoi ne pas tout simplement à l'aide d'un int * agir comme le Use-Count Class, tout comme le int* countPtr; utilisé dans le nouveau Smart Pointer Class:

class T
{
private:
    int* countPtr; //

    int* p;
    int val;

public:
    T(){
        p = new int();
        countPtr = new int();
        *countPtr = 1;
        val = 0;
    }
    T(T& t){
        p = t.p;
        countPtr = t.countPtr;
        val = t.val;
        *countPtr += 1;
    }
    T& operator = ( const T& rT){
        if(*countPtr>1){
            *countPtr -= 1;
        }
        else{
            delete p;
            delete countPtr;
        }
        p = rT.p;
        countPtr = rT.countPtr;
        val = rT.val;
        *countPtr += 1;
        return *this;
    }
    ~T(){
        if(*countPtr>1){
            *countPtr -= 1;
        }
        else{
            delete p;
            delete countPtr;
        }
    }

    int *get_ptr() const { return p; } 
    int get_int() const { return val; }

    //change the appropriate data member
    void set_ptr(int *ptr) { p = ptr; }
    void set_int(int i) { val = i; }
};

Test: j'ai testé le ci-dessus Smart Pointer Class aide d'un code comme le suivant, et il semble bien fonctionner.

int main()
{
    T t1;
    T t2(t1);
    T t3(t1);
    T t4;
    t4 = t1;

    return 0;
}

Vraie question: Est ce nouveau Smart Pointer Class avec simplement un int *countPtr suffisant? Si oui, pourquoi s'embêter à utiliser un Use-Count Class comme dans le livre? Si non, que dois-je manquer?

Ignorant le fait qu'il y a déjà quelques très bonnes smart pointeur de classes en C++11 de la bibliothèque standard et Boost, jetez un oeil à votre code par rapport à l'autre. Lequel est le plus simple?
Pourquoi avez-vous un val membre dans la classe?
Tout comme le val dans la version originale, c'est à dire une variable membre de smart pointeur de la classe.
Mais la variable n'a pas l'utilisation qui est visible ici.
Il semble que val est aussi mystérieusement ensemble, mais pas accessible dans l'original HasPtr

OriginalL'auteur herohuyongtao | 2014-01-03