c++中的拷贝是怎么回事,请举例说明浅拷贝和深拷贝?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; // 这次就没问题了
总结:
深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。 参考技术A 我列举一个例子来说吧:
你正在编写C++程序中有时后用到,操作符的重载。最能体现深层拷贝与浅层拷贝的,就是‘=’的重载。
看下面一个简单的程序:
class string
char *m_str;
public:
string(char *s)
m_str=s;
string();
string&operator=(const string s)
m_str=s.m_str;
return *this
;
int main()
string s1("abc"),s2;
s2=s1;
cout<<s2.m_str;
上面的 =重载其是就是实现了浅拷贝原因。是由于对象之中含有指针数据类型.s1,s2恰好指向同一各内存。所以是浅拷贝。而你如果修改一下原来的程序:
string&operator(const string&s)
if(strlen(m_str)!=strlen(s.m_str))
m_str=new char[strlen(s.m_str)+1];
if(*this!=s)
strcmp(m_str,s.m_str);
return *this;
这样你就实现了深拷贝,原因是你为被赋值对象申请了一个新的内存所以就是深拷贝。本回答被提问者采纳
以上是关于c++中的拷贝是怎么回事,请举例说明浅拷贝和深拷贝?的主要内容,如果未能解决你的问题,请参考以下文章
C++初阶:STL —— stringstring类 | 浅拷贝和深拷贝(传统写法和现代写法) | string类的模拟实现
C++初阶:STL —— stringstring类 | 浅拷贝和深拷贝(传统写法和现代写法) | string类的模拟实现