C++中浅拷贝与深拷贝之间的区别
2013-08-19 10:40
155 查看
c++默认的拷贝构造函数是浅拷贝
浅拷贝就是对象的数据成员之间的简单赋值,如你设计了一个类而没有提供它的复制构造函数,当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝,如:
class A
{ public:
A(int _data) : data(_data) { } // 带一个参数的构造函数。
A ( ) { } //默认的无参数构造函数
private:
int data ;
};
int main()
{
A a(5), b = a; // 仅仅是数据成员之间的赋值
}
这一句b = a;就是浅拷贝,执行完这句后b.data = 5;
如果对象中没有其他的资源(如:堆,文件,系统资源等),则深拷贝和浅拷贝没有什么区别,但当对象中有这些资源时,例如:
class A
{
public:
A(int _size) : size(_size){data = new int[size];} // 假如其中有一段动态分配的内存
A(){};
~A(){delete [] data;} // 析构时释放资源
private:
int* data;
int size;
};
int main()
{
A a(5), b = a; // 注意这一句
}
这里的b = a会造成未定义行为,因为类A中的复制构造函数是编译器生成的,所以b = a执行的是一个浅拷贝过程。我说过浅拷贝是对象数据之间的简单赋值,比如:
b.size = a.size; b.data = a.data; // Oops!
这里b的指针data和a的指针指向了堆上的同一块内存,a和b析构时,b先把其data指向的动态分配的内存释放了一次,而后a析构时又将这块已经被释放过的内存再释放一次。
对同一块动态内存执行2次以上释放的结果是未定义的,所以这将导致内存泄露或程序崩溃。
所以这里就需要深拷贝来解决这个问题,深拷贝指的就是当拷贝对象中有对其他资源(如堆、文件、系统等)的引用时(引用可以是指针或引用)时,对象的另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。如:
class A
{
public: A(int _size) : size(_size){data = new int[size];} // 假如其中有一段动态分配的内存
A(){};
A(const A& _A) : size(_A.size){data = new int[size];} // 深拷贝
~A(){delete [] data;} // 析构时释放资源
private:
int* data;
int size;
};
int main()
{
A a(5), b = a; // 这次就没问题了
}
总结:
深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。
浅拷贝就是对象的数据成员之间的简单赋值,如你设计了一个类而没有提供它的复制构造函数,当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝,如:
class A
{ public:
A(int _data) : data(_data) { } // 带一个参数的构造函数。
A ( ) { } //默认的无参数构造函数
private:
int data ;
};
int main()
{
A a(5), b = a; // 仅仅是数据成员之间的赋值
}
这一句b = a;就是浅拷贝,执行完这句后b.data = 5;
如果对象中没有其他的资源(如:堆,文件,系统资源等),则深拷贝和浅拷贝没有什么区别,但当对象中有这些资源时,例如:
class A
{
public:
A(int _size) : size(_size){data = new int[size];} // 假如其中有一段动态分配的内存
A(){};
~A(){delete [] data;} // 析构时释放资源
private:
int* data;
int size;
};
int main()
{
A a(5), b = a; // 注意这一句
}
这里的b = a会造成未定义行为,因为类A中的复制构造函数是编译器生成的,所以b = a执行的是一个浅拷贝过程。我说过浅拷贝是对象数据之间的简单赋值,比如:
b.size = a.size; b.data = a.data; // Oops!
这里b的指针data和a的指针指向了堆上的同一块内存,a和b析构时,b先把其data指向的动态分配的内存释放了一次,而后a析构时又将这块已经被释放过的内存再释放一次。
对同一块动态内存执行2次以上释放的结果是未定义的,所以这将导致内存泄露或程序崩溃。
所以这里就需要深拷贝来解决这个问题,深拷贝指的就是当拷贝对象中有对其他资源(如堆、文件、系统等)的引用时(引用可以是指针或引用)时,对象的另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。如:
class A
{
public: A(int _size) : size(_size){data = new int[size];} // 假如其中有一段动态分配的内存
A(){};
A(const A& _A) : size(_A.size){data = new int[size];} // 深拷贝
~A(){delete [] data;} // 析构时释放资源
private:
int* data;
int size;
};
int main()
{
A a(5), b = a; // 这次就没问题了
}
总结:
深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。
相关文章推荐
- 程序员面试金典: 9.13 C和C++ 13.4深拷贝和浅拷贝之间有何区别?请说明两者的用法。
- C、C++基础知识之二 sizeof和strlen之间的区别
- c++ 浅拷贝和深拷贝 指针和引用的区别 malloc(free)和new(delete)的区别 重载重写重定义
- 从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别
- Objective-C、C++以及C之间的区别
- C++ 赋值运算和拷贝赋值函数的区别
- C++中string和char的区别以及直接初始化和拷贝初始化
- C、C++、VC++ 三者之间的区别。
- java 与 c++ 、 C# 之间的区别与联系
- C++中 overload 、override、overwrite 之间的区别
- 指针赋值 int a[5]={.... ...}, a 、&a[0]、 &a三者之间的区别 浅析 C/C++求职面试必备考点(五)
- C++浅拷贝和深拷贝的区别
- C++类型转换操作符之间的区别
- 从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别
- C++中 overload 、override、overwrite 之间的区别
- c++中读写一行字符串和读写一个词之间的区别(c++ primer 5th)
- 从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别
- C++深拷贝和浅拷贝区别
- 完成字符串拷贝(sprintf、strcpy 及 memcpy 函数)函数之间的区别
- C/C++——++i、i+=1、i++之间的区别(附在学习boost时遇到的例子)