C++ Primer 随笔 Chapter 13 复制控制

本文深入探讨了C++中的复制控制机制,包括复制构造函数、赋值操作符和析构函数的作用与应用。详细解释了复制构造函数的定义和适用情况,以及C++中直接初始化与复制初始化的区别。同时,介绍了赋值操作符的工作原理,特别强调了赋值操作符的返回类型与内置类型赋值运算的相似性。此外,文章还阐述了析构函数的功能与重要性,并讨论了如何正确地实现析构函数以避免内存泄漏。最后,文章通过实例演示了管理指针成员的不同方法,包括常规指针行为、智能指针行为以及值型行为。

1.复制控制包含的内容:复制构造函数、赋值操作符、析构函数

2.复制构造函数:

  a. 定义:只有单个形参,而且该形参是对本类类型的引用,这样的构造函数被成为复制构造函数

  b. 适用情况:

     (1)根据一个类型的对象显示或隐式的初始化一个对象。

     (2)复制一个对象,将它作为参数传给一个函数

     (3)从函数返回时复制一个对象

     (4)初始化顺序容器中的元素(?)

     (5)根据元素初始化列表初始化数组元素(?)

3.C++中两种初始化的形式:直接初始化和复制初始化。

  a.直接初始化使用=符号,而直接初始化将初始化式放在圆括号中!但当用于类类型对象时,初始化的复制形式和直接形式有所不同:直接初始化调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始化首先使用指定构造函数创建一个临时对象,然后用复制构造函数将那个临时对象复制到正在创建的对象。

1 string null_book = "9-99-999-99-9"; //copy initialization
2 string dots(10,'.');                            //direct initialization
3 string empty_copy = new string();   //copy   initialization
4 string empty_direct;                     //direct initialization

  b.通常直接初始化和复制初始化仅在低级别优化上存在差异。但是不支持复制的类型或使用explicit构造函数的时候,他们有本质的区别:

1 ifstream file1("filename");//ok :direct initialization
2 ifstream file2 = "filename";//error: copy constructor is private;

4.赋值操作符

  a.合成赋值操作符:会执行逐个成员赋值:有操作数对象的每个成员赋值给做操作数对象的对应。除数组外,每个成员所属类型的常规方式进行赋值。对于数组,给每个数组元素赋值

  b.赋值操作符的返回类型应该与内置类型赋值运算返回的类型相同。内置类型的赋值运算返回对有操作数的引用,因此,复制操作符也返回对同一类类型的应用。

1 class Sales_item{
2 public:
3     Sales_item & operator = ( const Sales_item &);
4 }

  c.复制和赋值常一起使用

5.析构函数:

  a.撤销对象时会自动调用析够函数,撤销容器中的元素总是按逆序撤销。

  b.许多类不许要显示析够函数,只有当有些工作需要析够函数完成时,才需要析够函数。

  c.三法则:如果需要析够函数,则它也许要复制操作符和复制构造函数。

  d.合成析够函数:逆序撤销每个非static成员。

6.管理指针成员的三种方法:

  a.指针成员采取常规指针型行为。这样的类具有指针的所有缺陷但无需特殊的复制控制。

    (1)默认复制/赋值与指针成员(注:以下HasPtr是个简单的带指针成员变量的类)         

1 int obj = 0;
2 HasPtr ptr1(&obj, 42);  //int * member points to obj ,val is 42
3 HasPtr PTRW(PTR1);   //int * member ponts to obj,val is 42

    (2)指针共享同一个对象

    (3)可能出现悬垂指针  

  b.类可以实现所谓的“智能指针”行为。指针所指向的对象是共享的,但类能够防止悬垂指针。


1 class U_ptr {
2     friend class HasPtr;
3     int *ip;
4     size_t use;
5     U_Ptr(int *p):ip(p),use(1){}
6     ~U_Ptr(){ delete ip;}
7 }; //引入的计数器类

 c.类采取值型行为。指针所指向的对象是唯一的,由每个类对象独立管理。

 1 class HasPtr {
 2 public:
 3     HasPtr(const int &p,int i):ptr(new int(p),val(i)) {}
 4     HasPtr(const HasPtr &org):ptr(new int(*org.ptr)),val(orig.val){}
 5     HasPtr& operator=(const HasPtr&);
 6     ~HasPtr(){ delete ptr;}
 7 private:
 8     int *ptr;
 9     int val;
10 };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值