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 };
posted on 2013-09-17 16:35  水目沾  阅读(213)  评论(0编辑  收藏  举报