C++拷贝构造函数(浅拷贝、深拷贝)

下面举一个简单的例子说明对象之间的拷贝(此例中没有自定义拷贝构造函数,在调用拷贝构造函数的时候,编译器会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝)浅拷贝:

#include<iostream>

using namespace std;

class CExample

{

private:
int a;

public:

CExample(int b)

{

a=b;

}

void Show()

{

cout<<a<<endl;

}

};

int main()

{

CExample A(100);

CExample B=A;

B.Show();

return 0;

}

输出结果:
100

系统为对象B分配了内存并完成了与对象A的复制过程。形同类型对象是通过拷贝构造函数来完成整个过程的。

自定义构造函数(自定义拷贝构造函数是一种良好的编程风格,他可以组织编译器形成默认的拷贝构造函数,提高源码效率):

示例:

#include<iostream>

using namespace std;

class CExample

{

private:

int a;

public:

CExample(int b)

{

a=b;

}

CExample(const CExample& C)

{

a=C.a;

}

void Show()

{

cout<<a<<endl;

}

};

int main()

{

CExample A(100);

CExample B=A;

B.Show();

return 0;

}

输出结果:

100

当一个已经初始化的自定义类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。一下情况都会调用拷贝构造函数:

  • 一个对象以值传递的方式传入函数体
  • 一个对象以值传递的方式从函数返回
  • 一个对象需要通过另一个对象进行初始化

浅拷贝和深拷贝详解

在某些情况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是说把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那么A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(析构),这时A内存就成了野指针,出现运行错误。

两种拷贝方式可以简单的理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个重新分配的的过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。

下面举例说明深拷贝:

#include<iostream>

using namespace std;

class CA

{

private:

int a;

char* str;

public:

CA(int b,char* cstr)

{

a=b;

str=new char[b];

strcpy(str,cstr);

}

CA(const CA& C)

{

a=b;

str=new char[a];

if(str!=0)

  strcpy(str,C.str);

}

void Show()

{

cout<<str<<endl;

}

~CA()

{

delete str;

str=0;

}

};

void main()

{

CA A(10,"hello");

CA B=A;

B.Show();

return 0;

}

输出结果:

hello

上面的示例可以看出,首先初始化一个CA对象之后,在进行自定义拷贝构造函数把A中的变量str拷贝给对象B,在此之中,A可能会调用析构函数delete str操作,使得str变量的地址回收,如果在自定义拷贝构造函数中进行深拷贝操作,对象A析构释放资源后可能导致资源归属不清的情况而导致程序运行错误。深拷贝会在拷贝的时候重新给str分配内存单元,这样就可以在不出错的情况下独立操作B中的变量。

时间: 2024-12-18 14:36:42

C++拷贝构造函数(浅拷贝、深拷贝)的相关文章

C++拷贝构造函数(深拷贝与浅拷贝)

转自http://blog.csdn.net/lwbeyond/article/details/6202256/ 一. 什么是拷贝构造函数 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. 1 #include <iostream> 2 using namespace std; 3 4 class CExample { 5 private: 6 in

c++中 拷贝构造函数的深拷贝和浅拷贝--“浅拷贝”与“深拷贝”

C++中对象的复制就如同"克隆",用一个已有的对象快速地复制出多个完全相同的对象.一般而言,以下三种情况都会使用到对象的复制: (1)建立一个新对象,并用另一个同类的已有对象对新对象进行初始化,例如: class Rect { private: int width; int height; }; Rect rect1; Rect rect2(rect1); // 使用rect1初始化rect2,此时会进行对象的复制 (2)当函数的参数为类的对象时,这时调用此函数时使用的是值传递,也会产

c++语法:拷贝构造函数(深拷贝浅拷贝)

以拷贝的方式初始化对象 初始化对象时会调用构造函数,不同的初始化方式会调用不同的构造函数: 如果用传递进来的实参初始化对象,那么会调用普通的构造函数,我们不妨将此称为普通初始化: 如果用其它对象(现有对象)的数据来初始化对象,那么会调用拷贝构造函数,这就是以拷贝的方式初始化. 对于简单的类,默认的拷贝构造函数一般就够用了,我们也没有必要再显式地定义一个功能类似的拷贝构造函数.但是当类持有其它资源时,例如动态分配的内存.指向其他数据的指针等,默认的拷贝构造函数就不能拷贝这些资源了,我们必须显式地定

C++中拷贝构造函数

C++中拷贝构造函数 1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了.(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数.百度百科上是这样说的:拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化.其唯一的参数(对象的引用)是不可变的(const类型).此函数经常用在函数调用时用户定义类型的值传递及返回. 2.拷贝构造函数的形式 Class X { public: X(); X(cons

CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数

类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数 class Person{ public : Person():age(10), name(NULL); Person(int myage, char *myname); Person(const Person &a); ~Person(void); void set_age(int myage); void get_age(void); void set_other_age(Person &a, int b); private: i

【转载】C++拷贝构造函数(深拷贝,浅拷贝)

对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. #include <iostream>using namespace std;class CExample {private:     int a;public:     CExample(int b)     { a=b;}     void Show ()     {        cout<

C++拷贝构造函数(深拷贝,浅拷贝)

http://www.cnblogs.com/BlueTzar/articles/1223313.html 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. 1 #include <iostream> 2 using namespace std; 3 4 class CExample { 5 private: 6 int a; 7 public: 8

【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解

c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3977861.html 一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面看一个类对象拷贝的简单例子. #include<iostream

c++拷贝构造函数(深拷贝,浅拷贝)详解

一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面看一个类对象拷贝的简单例子. #include<iostream> using namespace std; class CExample { private: int a; public: //构造函数 CExample(int b) { a=b; printf("con