smart-ptr.cpp
上传用户:qdkongtiao
上传日期:2022-06-29
资源大小:356k
文件大小:3k
源码类别:

书籍源码

开发平台:

Visual C++

  1. #include <iostream>
  2. using std::ostream; using std::cout; using std::endl;
  3. #include <string>
  4. #include <cstddef>
  5. using std::size_t;
  6. //private class for use by HasPtr only
  7. class U_Ptr {
  8. friend class HasPtr;
  9. int *ip;
  10. size_t use;
  11. U_Ptr(int *p): ip(p), use(1) { }
  12. ~U_Ptr() { delete ip; }
  13. };
  14. class HasPtr {
  15. public:
  16.     // HasPtr owns the pointer; p must have been dynamically allocated
  17.     HasPtr(int *p, int i): ptr(new U_Ptr(p)), val(i) { }
  18.     // copy members and increment the use count
  19.     HasPtr(const HasPtr &orig):
  20.        ptr(orig.ptr), val(orig.val) { ++ptr->use; }
  21.     HasPtr& operator=(const HasPtr&);
  22.     // if use count goes to zero, delete the U_Ptr object
  23.     ~HasPtr() { if (--ptr->use == 0) delete ptr; } 
  24.     friend ostream& operator<<(ostream&, const HasPtr&);
  25.     // copy control and constructors as before
  26.     // accessors must change to fetch value from U_Ptr object
  27.     int *get_ptr() const { return ptr->ip; } 
  28.     int get_int() const { return val; }
  29.     // change the appropriate data member
  30.     void set_ptr(int *p) { ptr->ip = p; }
  31.     void set_int(int i) { val = i; }
  32.     // return or change the value pointed to, so ok for const objects
  33.     // Note: *ptr->ip is equivalent to *(ptr->ip)
  34.     int get_ptr_val() const { return *ptr->ip; } 
  35.     void set_ptr_val(int i) { *ptr->ip = i; }
  36. private:
  37.     U_Ptr *ptr;        // points to use-counted U_Ptr class
  38.     int val;
  39. };
  40. HasPtr& HasPtr::operator=(const HasPtr &rhs)
  41. {
  42.     ++rhs.ptr->use;     // increment use count on rhs first
  43.     if (--ptr->use == 0)
  44.          delete ptr;    // if use count goes to 0 on this object, delete it
  45.     ptr = rhs.ptr;      // copy the U_Ptr object
  46.     val = rhs.val;      // copy the int member
  47.     return *this;
  48. }
  49. ostream& operator<<(ostream &os, const HasPtr &hp)
  50. {
  51.     os << "*ptr: " << hp.get_ptr_val() << "tval: " << hp.get_int() << endl;
  52.     return os;
  53. }
  54. int main()
  55. {
  56. int obj = 0;
  57. HasPtr ptr1(&obj, 42);
  58. HasPtr ptr2(ptr1);
  59. cout << "(1) ptr1: " << ptr1 << endl << "ptr2: " << ptr2 << endl;
  60. ptr1.set_ptr_val(42); // sets object to which both ptr1 and ptr2 point
  61. ptr2.get_ptr_val();   // returns 42
  62. cout << "(2) ptr1: " << ptr1 << endl << "ptr2: " << ptr2 << endl;
  63. ptr1.set_int(0);   // changes s member only in ptr1
  64. ptr2.get_int();    // returns 42
  65. ptr1.get_int();    // returns 0
  66. cout << "(3) ptr1: " << ptr1 << endl << "ptr2: " << ptr2 << endl;
  67. }
  68. void f3()
  69. {
  70. int obj;
  71. HasPtr p1(&obj, 42);
  72. HasPtr p2(p1);  // p1 and p2 both point to same int object
  73. HasPtr p3(p1);  // p1, p2, and p3 all point to same int object
  74. }