C++ 复制构造函数

  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.

  

  

  

时间: 2024-08-10 17:17:56

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

剑指offer 复制构造函数

复制构造函数: A(const A &other){value=other.value;} 也就是传值参数改为常量引用. #include<iostream> using namespace std; class A { private: int value; public: A(int n){value=n;} A(const A &other){value=other.value;} void print(){ cout<<value<<endl;

复制构造函数

// 复制构造函数.cpp : 定义控制台应用程序的入口点.//复制构造函数:类(const 类&对象(随便起))/*Box(const Box&box){length = box.length;width = box.width;height = box.height;}*/ #include "stdafx.h"#include<iostream>using namespace std;class Box{private:    int length; 

C++复制构造函数和赋值符的区别

From  http://blog.csdn.net/randyjiawenjie/article/details/6666937 感谢原作者分享. class CTest{public: CTest(); //构造函数 CTest(const CTest &); //复制构造函数 CTest & operator = (const CTest &); //赋值符}; CTest::CTest(){ cout<<"Constructor of CTest&qu

复制构造函数的调用

1 #include <iostream> 2 using namespace std; 3 4 class Test 5 { 6 public: 7 Test(int n = 1) 8 { 9 val = n; 10 cout << "Con." << endl; 11 } 12 13 Test(const Test& t) 14 { 15 val = t.val; 16 cout << "Copy con."

C++类的复制构造函数和赋值运算符

前言: C++面向对象的编程过程中,凡是在类中运用到动态内存分配的时候总是会写一个显示的复制构造函数和赋值重载运算符,本文将结合C++ Primer Plus一书的内容分析下原因: 一.在C++编程中如果没有编写下列成员函数,系统会自动的提供: (1)构造函数 (2)析构函数 (3)地址运算符 (4)赋值构造函数 (5)赋值运算符 其中(1)-(3)在编程中不会产生什么影响,但是(4)(5)会造成较大的影响 二.赋值构造函数 1.函数原型  Class_name(const Class_name

一段代码引起的对C++构造函数、析构函数,复制构造函数,运算符重载的深度理解

代码和解释: #include "stdafx.h" #include <stdio.h> #include <string> #include <iostream> using namespace std; class test{ int *p; public: test(int value){ p = new int(value); cout<<"Execute Constructor>>"<&l

对象 &amp;&amp; 复制构造函数

复制构造函数必须将形参指定为 const 引用 若复制构造函数写成如下: CBox(CBox initB); 由于是按值传递,所以编译器会首先创建对象的副本,而创建对象的副本需要调用复制构造函数,又会创建新的对象,新对象又会调用复制构造函数 会持续不休,最终得到对复制构造函数的无穷调用. 解决方法如下: CBox(const CBox & initB); 由于是引用形参,因此没有复制发生,const 限定符用来确保该函数不能修改实参. class CMessage { private: char

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

1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作符:返回值是本类的引用类型,参数类型是所属类的类型,且参数是一个const引用. 作用与复制构造函数相同. 其声明如下: 1 Sales_item& operator=(const Sales_item& rig); 3.什么情况下需要我们自己实现复制构造函数和赋值操作符? 一般情况下,C++

复制构造函数2&mdash;&mdash;深入理解

//如果不显示定义复制构造函数,编译会出错,原因是:在创建对象s2时,调用默认复制构造函数并用对象s1对其进行初始化,致使s2中指针 //与s1中指针指向同一储存空间,当一个对象生命周期结束后调用析构函数释放内存空间后,另一个变量的指针悬空,无法正常使用. //浅复制 //再用一个对象初始化另一个对象时,只复制了成员,没有复制资源(指堆内存 ,数据成员没有具体值),使两个对象同时指向同一资源, //如果不存在资源矛盾,程序可以正常运行 #include <cstring> #include&l

对象做函数参数和函数返回值时,调用复制构造函数,构造函数,析构函数的情况

// 对象做函数参数和返回值.cpp : 定义控制台应用程序的入口点.//exit(0)表示正常退出程序,exit(0)表示异常退出 //在调用input时,编译器用对象A去创建了形参对象temp,调用了复制构造函数,对象A中的数据复制给了对象temp// 在input函数中,执行temp.set(s),为对象temp中数据成员str申请了动态储存空间,并设置了输入的字符串//并没有改变实参A中的数据成员str的储存空间,故在执行语句A.show()后输出的字符串并没有改变.在函数调用结束后 /