C++类的设计中,如果某些函数没有显式定义,C++会自动生成,复制构造函数便是其中之一,其他的还有默认构造函数、赋值操作符、默认析构函数、地址操作符。一个类的复制构造函数的原型一般为: Class_name (const Class_name &);

一、何时调用复制构造函数

  在新建一个对象并将其初始化为同类对象的时候,常常会调用复制构造函数,如:

    Class_name A(B);

    Class_name A = B ;

    Class_name A = Class_name(B);

    Class_name *p = new Class_name(A);// 用A初始化一个匿名对象,并将其地址赋予指针P

  每当程序生成对象副本时,编译器都会调用复制构造函数。具体地说,当函数按值传递对象或生成临时对象时,编译器都会调用复制构造函数。如当3个Vector对象相加时,编译器会调用复制构造函数来生成临时对象。

二、复制构造函数的浅复制

  默认的复制构造函数是浅复制,即逐个复制非静态成员数据的值。

  (1)如果类成员是另一个类的对象,那么将调用另一个对象的复制构造函数;

  (2)静态成员数据不被复制,因为它们属于整个类,而不是一个对象。

  (3)如果成员中含有含有指针P,那么它的地址也会赋给新的对象中相应的P,这样会导致两个或多个变量指向同一个指针——比较危险的一件事。

三、复制构造函数的深复制

  显式地定义复制构造函数可以有效解决浅复制的弊端。下面以一个自定义的MyString类作为例子:

  假若是使用默认的复制构造函数,则程序很容易崩溃,比如当你创建了对象A,用A初始化B(A和B的str指向同一个地址),然后销毁A(此时A的str指向的内存已被收回),之后你如果想销毁B,则可能使程序崩溃。

  解决方法是显式定义复制构造函数:

  

  在函数中使用动态内存分配,在函数里面也可以显性改变静态数据成员的值。与new相对应,在析构函数中使用delete关键字销毁内存:

  

  

  //End.

  

  

  

C++ 复制构造函数的更多相关文章

  1. 剑指offer:赋值运算符函数和复制构造函数

    赋值运算符函数 对于定义一个赋值运算符函数时,需要注意一下几点: (1)函数的返回类型必须是一个引用,因为只有返回引用,才可以连续赋值 (2)传入的参数声明为常量引用,可以提高代码效率,同时赋值运算函 ...

  2. 剑指offer 复制构造函数

    复制构造函数: A(const A &other){value=other.value;} 也就是传值参数改为常量引用. #include<iostream> using name ...

  3. 编译器角度看C++复制构造函数

    [C++对象模型]复制构造函数的建构操作 关于复制构造函数的简单介绍,可以看我以前写过的一篇文章C++复制控制之复制构造函数该文章中介绍了复制构造函数的定义.调用时机.也对编译器合成的复制构造函数行为 ...

  4. C++ 复制控制之复制构造函数

    7月26日更新: 过了这么长的时间回过头来看,发现文章中有几个点说错(用红字标出): 构造函数不是只有唯一一个参数,它也可以是多参数形式,其第二参数及后继以一个默认值供应. 不是没有声明复制控制函数时 ...

  5. 我的c++学习(7)引用和复制构造函数

    一.引用 什么是引用? 引用又称别名(alias),是一种非常特殊的数据类型.它不是定义一个新的变量,而是给一个已经定义的变量重新起一个别名,也就是 C++系统不为引用类型变量分配内存空间.引用主要用 ...

  6. C++中的复制构造函数

    与C++中的构造函数相同,复制构造函数在对象生成过程中同样进行插入对应的Vtable虚表,但在成员变量赋值时,除具有复制构造函数的成员对象外,编译器合成复制构造函数其余均采用”Bitwise copy ...

  7. C++学习基础六——复制构造函数和赋值操作符

    1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作 ...

  8. C++中复制构造函数

    复制构造函数 复制构造函数用于: 根据另一个同类型的对象显示或隐式初始化一个对象 复制一个对象,将它作为实参传给一个函数 从函数返回时复制一个对象 初始化顺序容器中的元素 根据元素初始化式列表初始化数 ...

  9. 深入理解c++构造函数, 复制构造函数和赋值函数重载(operator=)

    注 以下代码编译及运行环境均为 Xcode 6.4, LLVM 6.1 with GNU++11 support, Mac OS X 10.10.2 调用时机 看例子 // // main.cpp / ...

随机推荐

  1. uC/OS-II互斥信号(OS_mutex)块

    /*************************************************************************************************** ...

  2. bootstrap标签引入地址

    http://www.bootcdn.cn/bootstrap/ <link rel="stylesheet" href="http://apps.bdimg.co ...

  3. js操作DOM动态添加和移除事件

    非IE下,注意事件名不带on,如onclick为click 添加事件:DOM对象.addEventListener('事件名',函数名,true/false); 删除事件:DOM对象.removeEv ...

  4. Java数据结构——队列

    //================================================= // File Name : Queue_demo //-------------------- ...

  5. JSP 核心标签库

    1 JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 2 JSTL标签库分类 核心标 ...

  6. 获取<img src="sdf.jpg" Big="sf.jpg">中的big的值

    原代码: <img src="sdf.jpg" Big="sf.jpg" onclick="getsrc($(this).attr(" ...

  7. sqlmap写文件为空之谜

    恰逢有一个SQL注入可以通过sqlmap进行,而且权限高得离谱,直接就是root权限.既然是root权限当然是想直接getshell咯.可是只是sqlmap -u xxx --os-shell的时候却 ...

  8. JS获取当前对象大小以及屏幕分辨率等...

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta nam ...

  9. aop测试jdk代理机制

    //测试jdk代理机制 @Test public void testProxy(){ final UsbDisk usbDisk = new UsbDisk(); //类加载器,接口,匿名内部类 // ...

  10. C#设计模式 - 观察者模式(使用委托)

    1.概念 观察者模式(有时又被称为发布-订阅Subscribe>模式.模型-视图View>模式.源-收听者Listener>模式或从属者模式)是软件设计模式的一种.在此种模式中,一个 ...