码迷,mamicode.com
首页 > 其他好文 > 详细

Copy Control and Resource Management

时间:2015-01-20 20:18:27      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:

Ordinarily classes that manage resources that do not reside in the class must define the copy-control members. Once a class needs a destructor, it almost surely needs a copy constructor and copy-assignment operator as well.

  In order to define these members, we first have to decide what copying an object of our type will mean. In general, we have two choices: we can define the copy operations to make the class behave like a value or like a pointer.

1.Classes That Act Like Values

 1 #include <string>
 2 using std::string;
 3 
 4 class Has_ptr
 5 {
 6 public:
 7     // constructor with default argument
 8     Has_ptr(const std::string &s = std::string()) :
 9       ps(new std::string(s)), i(0) { }
10     // copy destructor: 
11     //each Has_ptr has its own copy of the string to which ps points
12     Has_ptr(const Has_ptr &p) :
13       ps(new std::string(*p.ps)), i(p.i) { }
14     // assignment operator
15     Has_ptr &operator=(const Has_ptr &rhs);
16     // destructor: free the memory allocated in constructor
17     ~Has_ptr() { delete ps; }
18 private:
19     std::string *ps;
20     int i;
21 };
22 
23 // assignment operator: can handle self-assignment
24 Has_ptr &Has_ptr::operator=(const Has_ptr &rhs)
25 {
26     string *newp = new string(*rhs.ps);    // copy the underlying string
27     delete ps;    // free the old memory
28     ps = newp;    // copy data from rhs into this object
29     i = rhs.i;
30     return *this;
31 }

There are two points to keep in mind when you write an assignment operator:

  • Assignment operators must work correctly if an object is assigned to itself.
  • Most assignment operators share work with the destructor and copy constructor.

A good pattern to use when you write an assignment operator is to first copy the right-hand operand into a local temporary. After the copy is done, it is safe to destroy the existing members of the left-hand operand. Once the left-hand operand is destroyed, copy the data from the temporary into the members of the left-hand operand.

What if Has_ptr didn‘t define the copy constructor(Exercise 13.24)?

 We‘ll use the synthesized version of the copy constructor. In this case, we have introduced a serious bug! Synthesized copy constructor copy the pointer member, meaning that multiple Has_ptr objects may be pointing to the same memory.

2.Defining classes That Act Like Pointers

In this case, though, the destructor of Has_ptr cannot unilaterally free its associated string. It can do so only when the last Has_ptr pointing to that string goes away.

  When we copy or assign a Has_ptr object, we want the copy and the original to point to the same string.

 

 1 #include <string>
 2 using std::string;
 3 
 4 class Has_ptr
 5 {
 6 public:
 7     // constructor allocates a new string and a new counter, which it sets to 1
 8     Has_ptr(const std::string &s = std::string()) :
 9       ps(new std::string(s)), i(0), use(new std::size_t(1)) { }
10     // copy constructor copies all three data member and increment the counter
11     Has_ptr(const Has_ptr &p) :
12       ps(p.ps), i(p.i), use(p.use) { ++*use; }
13      Has_ptr &operator=(const Has_ptr &rhs);
14      ~Has_ptr();
15 private:
16     std::string *ps;
17     int i;
18     std::size_t *use;    // member to keep track of how many objects share *ps
19 };
20 
21 Has_ptr::~Has_ptr()
22 {
23     if (--*use == 0)    // if the reference count goes to 0
24     {
25         delete ps;        // delete the string
26         delete use;        // delete the counter
27     }
28 }
29 
30 // the operator must handle self-assignment.
31 // we do so by increment the count in rhs before 
32 // decrementing the count in the left-hand object
33 Has_ptr &Has_ptr::operator=(const Has_ptr &rhs)
34 {
35     ++*rhs.use;        // increment the use count of the right-hand operand
36     if (--*use == 0)    
37     {                    // then decrement this object‘s counter
38         delete ps;        // if no other users
39         delete use;        // free this object‘s allocated members
40     }
41     ps = rhs.ps;        // copy data from rhs into this object
42     i = rhs.i;
43     use = rhs.use;
44     return *this;        // return this object
45 }

 

Copy Control and Resource Management

标签:

原文地址:http://www.cnblogs.com/90programmer/p/4237096.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!