浅拷贝和深拷贝

目录

一.什么是浅拷贝,什么是深拷贝

二.浅拷贝发生错误过程

三.关于浅拷贝的详细讨论

四.深拷贝 


 

一.什么是浅拷贝,什么是深拷贝

 浅拷贝:位拷贝,拷贝构造函数,赋值重载
    多个对象共用同一块资源,同一块资源释放多次,崩溃或者内存泄漏
深拷贝:每个对象共同拥有自己的资源,必须显式提供拷贝构造函数和赋值运算符

二.浅拷贝发生错误过程

 在程序运行过程中,如果一个对象的变量B动态开辟了一个内存空间,在进行位拷贝的时候,就把B的值完全赋给A。在赋值过程中,就是A中变量与B中变量指向同一内存空间。但是如果B将内存释放,
A中的指针就没有了指向,也就是野指针,这样就会发生运行错误 。

三.关于浅拷贝的详细讨论

1.默认构造函数可以完成对象的数据成员简单的复制
2.对象的数据资源是由指针指向的堆时,默认的拷贝构造函数只是将指针复制

3.有指针,有默认的拷贝构造函数才会发生浅拷贝

#include <iostream>
using namespace std;
class Line{
   public:
      int getLength( void );
      Line( int len );                 
      ~Line();   
	  void set(int m)
	  { 
	    *ptr=m; 
	   }               
   private:
      int *ptr;
};
Line::Line(int len)
{
    cout << "调用构造函数" << endl;
    ptr = new int;//在堆上开辟一个空间,指针ptr指向堆上新分配的内存空间  
    *ptr = len;//把传递进来的参数放在ptr指向的内存空间中 
}
Line::~Line()
{
    cout << "开始释放内存" << endl;
    delete ptr;
    cout << "释放内存完毕" << endl;
}
int Line::getLength(  )
{ 
  return *ptr;//返回ptr所指向空间里面的值 
  }

int main( )
{
	Line line0(10);	//创建line0这个对象,并且调用构造函数
	cout << "line0 大小 : " << line0.getLength() <<endl;
	Line line1=line0;//用line0初始化line1,一定会调用拷贝构造函数,但是没有自定义的拷贝构造函数,
	//所以一定会调用默认的拷贝构造函数,而前面提到默认的拷贝构造函数只是将指针复制,
	//所以line0和line1的指针指向同一个内存空间 ,该内存空间存放的是10 
	cout << "line1 大小 : " << line1.getLength() <<endl;
	line1.set(100);//line1通过set()函数去修改它的指针所指向空间里面的值,即将10改为100 
	cout << "line0 大小 : " << line0.getLength() <<endl;//输出100 
	cout << "line1 大小 : " << line1.getLength() <<endl;//输出100 
	return 0;//程序结束后先析构了line1,等到析构line0的时候,指针已经悬空了没有可以析构的 
}

四.深拷贝 

#include <iostream>
using namespace std;
class Line{
   public:
      int getLength( void );
      Line( int len );            
      Line( const Line &obj); //自定义了一个拷贝构造函数,类内声明    
      ~Line();  
	  void set(int m)
	  {
	  	*ptr=m;
	   }                
   private:
      int *ptr;
};
Line::Line(int len)
{
    cout << "调用构造函数" << endl;
    ptr = new int;//在堆上申请一个空间,指针ptr指向堆上新分配的内存空间
    *ptr = len;
}
Line::Line(const Line &obj)//拷贝构造函数在类外定义 
{
    cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
    ptr = new int;//在堆上申请一个空间,指针ptr指向堆上新分配的内存空间,此时的ptr是当前对象line1的ptr 
    *ptr = *obj.ptr;//将obj就是line0,*obj.ptr是将line0指向的内存空间里面的10取出来,
	//放进当前line1的ptr指向的内存空间 
}
Line::~Line(){
    cout << "开始释放内存" << endl;
    delete ptr;
    cout << "释放内存完毕" << endl;
}
int Line::getLength(  )
{
    return *ptr;
}
void display(Line obj){
   cout << "line 大小 : " << obj.getLength() <<endl;
}
int main( )
{
	Line line0(10);	//创建line0这个对象,并且调用构造函数,将10传参给len
	cout << "line0 大小 : " << line0.getLength() <<endl;
	Line line1=line0;//用line0初始化line1,一定会调用拷贝构造函数,
	//所以一定会调用自定义的拷贝构造函数,
	cout << "line1 大小 : " << line1.getLength() <<endl;
	line1.set(100);//line1通过set()函数去修改它的指针所指向空间里面的值,即将10改为100 
	cout << "line0 大小 : " << line0.getLength() <<endl;//输出10 
	cout << "line1 大小 : " << line1.getLength() <<endl;//输出100 
	return 0;//程序结束后先析构了line1,然后析构line0
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值