为了定义拷贝构造函数和拷贝赋值运算符,我们首先必须确认此类型对象的拷贝语义。通常可以定义拷贝操作,使类的行为看起来像一个值或者像一个指针(即所谓的深拷贝和浅拷贝)

类的行为像一个值,意味着它应该也有自己的状态。当我们拷贝一个像值的对象时,副本和原对象是完全独立的。改变副本不会对原对象有任何影响,反之亦然

行为像指针的类则共享状态。当我们拷贝一个这种类的对象时,副本和原对象使用相同的底层数据。改变副本也会改变原对象,反之亦然

在我们使用过的标准库类中,标准库容器和 string 类的行为像一个值。shared_ptr 提供类似指针的行为。IO 类型和 unique_ptr 不允许拷贝或赋值,因此它们的行为既不像值也不像指针

 

行为像值的类:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class HasPtr{
 5 public:
 6     HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) {}
 7     HasPtr(const HasPtr &p) : ps(new std::string(*p.ps)), i(p.i) {}
 8     HasPtr& operator=(const HasPtr&);
 9     ~HasPtr(){
10         delete ps;
11     }
12 
13     ostream& print(ostream &os){
14         os << i << " " << *ps << " " << ps;
15         return os;
16     }
17 
18 private:
19     std::string *ps;
20     int i;
21 };
22 
23 HasPtr& HasPtr::operator=(const HasPtr &rhs){
24     auto newp = new string(*rhs.ps);//为了避免两个对象中ps指针相同时出错先将rhs.ps中的内容存放到一个新开辟的空间newp中
25     delete ps;//释放旧内存
26     ps = newp;
27     i = rhs.i;
28     return *this;
29 }
30 
31 int main(void){
32     HasPtr s1("hello");
33     HasPtr s2 = s1;
34     HasPtr s3;
35     s3 = s1;
36 
37     s1.print(cout) << endl;
38     s2.print(cout) << endl;
39     s3.print(cout) << endl;
40 
41 // 输出:
42 //     0 hello 0x2a811d8
43 //     0 hello 0x2a811a8
44 //     0 hello 0x2a81198
45 
46     return 0;
47 }
View Code

相关文章:

  • 2021-11-22
  • 2021-08-10
  • 2022-12-23
  • 2021-12-04
  • 2022-02-04
  • 2021-04-12
  • 2021-12-10
  • 2021-07-09
猜你喜欢
  • 2022-12-23
  • 2021-07-04
  • 2022-12-23
  • 2022-01-20
  • 2022-01-27
  • 2021-07-13
  • 2022-12-23
相关资源
相似解决方案