C++ Primer学习笔记——$13 拷贝控制

转载 2011年01月19日 15:08:00

题记:本系列学习笔记(C++ Primer学习笔记)主要目的是讨论一些容易被大家忽略或者容易形成错误认识的内容。只适合于有了一定的C++基础的读者(至少学完一本C++教程)。

 
作者: tyc611, 2007-01-29
   本文主要讨论C++类定义中的拷贝控制(copy control):拷贝构造函数、赋值操作符和析构函数。
   如果文中有错误或遗漏之处,敬请指出,谢谢!
   C++类中有四个不可或缺的部分,那就是构造函数、拷贝构造函数、赋值操作符和析构函数。如果类中没有定义这些函数,那么编译器将为类自动生成这些函数。当然,你也可以通过private控制策略限定不使用拷贝构造函数和赋值操作符。
 
   其中,拷贝构造函数、赋值操作符和析构函数总称为拷贝控制(copy control)。
 
   当类中有指针类数据成员时,一般都需要自已实现类的拷贝控制。通常有两种处理策略:一是定义值型类,每个类保留一份指针指向的对象的拷贝;另一种更常用的策略是使用智能指针(smart pointer),其通用技术是采用引用计数(reference count)来实现共享指针指向的对象。
 
拷贝构造函数
 
   我们知道C++中变量初始化有两种形式:直接初始化和拷贝初始化。直接初始化将初始化放在圆括号中,而拷贝初始化使用=符号。对于内置类型,这两者基本上没有区别。但对于类类型,两种方式是有区别的:直接初始化直接调用与实参匹配的构造函数;而拷贝初始化总是调用拷贝构造函数,具体而言,就是拷贝初始化首先使用指定构造函数创建一个临时对象,然后用拷贝构造函数将那个临时对象拷贝到正在创建的对象。
 
   支持拷贝初始化主要是为了与C的用法兼容。当情况允许时,可以允许编译器跳过拷贝构造函数直接创建对象,但编译器没有义务这样做。注:事实上大多数编译器都跳过了拷贝构造函数,因为这完全可以跳过,比如在VC6.0和MinGW2.05。
 
   我们知道可以用表示容量的单个参数来初始化容器,容器的这种构造方式使用了默认构造函数和拷贝构造函数。例如:
   vector<string> svec(5);
编译器首先使用string的默认构造函数创建一个临时值来初始化svec,然后使用拷贝构造函数将临时对象拷贝到svec的每个元素。示例代码如下:
#include <iostream>
#include <vector>
using namespace std;

class Test {
public:
    Test() {
        cout<<"Contructor"<<endl;
    }
    Test(const Test& t) {
        cout<<"copy Contructor"<<endl;
    }
};

int main() {
    vector<Test> tvec(5);
    return 0;    
}

输出结果为:(MinGW 2.05和VC6.0)
Contructor
copy Contructor
copy Contructor
copy Contructor
copy Contructor
copy Contructor

 
   对于元素为类类型的数组,可以使用数组初始化列表来提供显示元素初始化。此时,使用拷贝初始化来初始化每个元素。根据指定值创建适当类型的元素,然后用拷贝构造函数将该值拷贝到相应元素。当然,同前面一样,是否跳过拷贝构造函数取决于编译器(事实上,大多数编译器跳过了这步)。
 
   拷贝构造函数的形参是一个类类型引用(否则,参数本身就需要过拷贝构造函数了),但一般情况下,我们使用const修饰。并且,一般不应该设置为explicit。
 
   有时需要禁止拷贝类,例如,iostream类就不允许拷贝。这时,应当显示声明拷贝构造函数为private,此时可以不定义该函数。若声明为private且进行了函数定义,则类的友元和成员仍然可以进行拷贝。
 注意:声明而不定义成员函数是合法的,但是,使用未定义成员的任何尝试将导致链接失败。
 
合成的拷贝构造函数
 
   如果我们没有定义拷贝构造函数,则编译器会自动生成一个,把这个自动生成的拷贝构造函数叫合成的拷贝构造函数(Synthesized Copy Constructor)。合成的拷贝构造函数执行逐个成员初始化,将新对象初始化为原对象的副本。如果成员是内置类型,则执行位拷贝;如果成员是类类型,则调用相应的拷贝构造函数;如果成员是数组类型,则分别对每个数组元素进制拷贝。
 
赋值操作符
 
   赋值操作符的右操作数一般以const引用传递,为了与内置类型的行为一致,常返回该类类型的引用。通常,拷贝构造函数和赋值操作符是同时出现的,定义了一个就应当定义另一个。
 
  赋值操作符一个必须小心的地方时检查自赋值。
 
析构函数
 
   三法则(rule of three):如果类需要自定义析构函数,则它往往也需要拷贝构造函数和赋值操作符。
 
   合成的析构函数按成员在类中声明次序的逆序来撤销成员。
 
   析构函数与拷贝构造函数或者赋值操作符之间的一个重要区别是:即使我们编写了自己的析构函数,在自定义析构函数运行结束后,合成析构函数仍然将继续运行,它来完成成员数据的撤销工作。
 

   如果文中有错误或遗漏之处,敬请指出,谢谢!


 

参考文献:
[1] C++ Primer(Edition 4)
[2] Thinking in C++(Volume Two, Edition 2)
[3] International Standard:ISO/IEC 14882:1998

c++ primer(第五版)学习笔记及习题答案代码版(第十三章)拷贝控制

笔记较为零散,都是自己不熟悉的知识点。 习题答案至于一个.h 和.cc 中,需要演示某一题直接修改 #define NUM****, 如运行13.30题为#define NUM1330; chapt...
  • refuil
  • refuil
  • 2016年05月31日 17:50
  • 1503

《c++ primer》 第13章 拷贝控制 学习笔记

第 13 章 拷贝控制 1.拷贝,赋值与销毁 对初学c++的程序员来说,必须定义对象拷贝,移动,赋值或销毁时做什么。 拷贝构造函数:如果一个构造函数的参数是本身的引用,且其他的参数都有默认值,此...
  • wwh578867817
  • wwh578867817
  • 2014年12月15日 16:53
  • 2403

c++primer(第五版) 第十三章 拷贝控制习题答案

纯原创    转载请注明出处:http://blog.csdn.net/axuan_k 13.2    13.3   13.4    13.5 #include using namespa...
  • AXuan_K
  • AXuan_K
  • 2016年03月29日 12:04
  • 2620

C++ Primer 学习笔记——拷贝控制

拷贝构造函数直接初始化:编译器使用普通的函数匹配,来选择与我们提供的参数最匹配的构造函数 拷贝初始化:将右侧的对象拷贝到正在创建的对象中,通常使用拷贝构造函数来完成调用拷贝构造函数 除了=还有, 将...
  • amy260231120
  • amy260231120
  • 2016年03月07日 14:54
  • 120

C++ Primer学习笔记(13)——封装、继承、多态

C++ 是一种典型的面向对象的编程语言,其最显著地特点是封装、继承和多态。充分理解封装、继承、多态是如何实现的,学好C++就不是难事了。...
  • zhangyumumu
  • zhangyumumu
  • 2015年07月08日 16:45
  • 817

读书笔记:C++ primer 5th edition--chapter13.拷贝控制

part1.拷贝、赋值与销毁 1.拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符,析构函数对应的操作称为拷贝控制操作 2.拷贝构造函数 1)第一个参数必须为引用类型。因为在函数调用过...
  • lebula
  • lebula
  • 2016年10月12日 01:32
  • 188

C++primer学习笔记----拷贝控制

一个类通过定义五种特殊的成员函数来控制拷贝控制操作:拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符、析构函数。...
  • u012677715
  • u012677715
  • 2017年06月10日 13:01
  • 200

2012/1/13 《C++ Primer Plus》第五章:循环和表达式 学习笔记

《C++ Primer Plus》第五章学习笔记 57:C++表达式是值或值与操作符的组合,每个C++表达式都有值。   58:++x; x++;这两条语句作用效果相同。对于内置类型,不会有差别...
  • Zyearn
  • Zyearn
  • 2012年01月14日 17:09
  • 592

《C++ Primer》读书笔记——第十三章_拷贝控制

一个类有5种特殊的成员函数:拷贝构造函数、拷贝赋值运算符、覅用构造函数、移动赋值运算符、析构函数。如果没有定义这些拷贝控制成员,编译器会自动为它定义缺失的操作。 13.1  拷贝构造函数 如果一个...
  • u011389977
  • u011389977
  • 2016年09月22日 00:04
  • 567

C++ Primer学习笔记——$11 泛型算法

  • 2009年04月26日 12:47
  • 118KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ Primer学习笔记——$13 拷贝控制
举报原因:
原因补充:

(最多只允许输入30个字)