In book C++ Primer 13.5.1
, it implement a Smart Pointer Class using a Use-Count Class. Their implementation is as follows:
Use-Count Class
// 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; } };
Smart Pointer Class
/* 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; };
Wonder: I am curious about why not simply using a int *
to act like the Use-Count Class
, just like the int* countPtr;
used in the following new 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: I tested the above Smart Pointer Class
using code like the following and it seems working well.
int main()
{
T t1;
T t2(t1);
T t3(t1);
T t4;
t4 = t1;
return 0;
}
Real question: Is this new Smart Pointer Class
with simply a int *countPtr
sufficient enough? If yes, why bother to use an extra Use-Count Class
like in the book? If no, what do I miss?
val
member in the class? – Vidalval
in the original version, i.e. member variable of smart-pointer class. – Whichsoeverval
is also mysteriously set, but not accessible in the originalHasPtr
– Doone