浅拷贝、深拷贝构造函数

1、 深浅拷贝是指深拷贝构造函数和浅拷贝构造函数。构造函数总共有三类:无参构造函数、有参数构造函数、拷贝构造函数。
2、 当有属性在堆区开辟的,一定要提供拷贝构造函数,防止浅拷贝带来的问题。(堆区需要手动的清除内存,如果没有去除,系统在结束后会去除。但是析构函数在系统结束之前执行,浅拷贝导致析构函数运行错误)

1、概念

  • 无参构造函数,又称位默认构造函数,默认构造函数的意思是编译器会自动生成,不需要人工的手写。默认构造函数的要求是:函数名与类名相同,没有参数,没有返回值。
  • 有参构造函数:有参数传递的构造函数。
  • 拷贝构造函数:使用另一个对象实例化自己的对象。具体见下面的代码。

2、浅拷贝
没有书写拷贝构造函数时,编译器使用默认拷贝构造函数,就是下面的值传递的构造。我们一般会在有参构造函数做如下的赋值操作:

Person()
{
public:
  int age;
  int * weight;
  //有参构造函数
 Person(int n_age,int n_weight)
 {
    age=n_age;
    weight=n_weight;
 }
 Person(const Person &p)
 {
     age=p.age;
     weight=p.weight;
 }
}
void test()
{
   //初始化对象p1,年龄20,体重140
   Person p1(20,140);
   //使用p1对象赋值给p2,相当于把p1对象拷贝给p2
   Person p2(p1);
}
int main()
{
   test();
   return 0;
}
  • 注意上述的age=n_age;和weight=n_weight;语句,这是一个值传递。p2对象由p1对象初始化,也就是我们说的浅拷贝
  • 当函数结束运行时,p1和p2对象都要进行析构,p1先创建的,所以后析构。因此其过程就是p1构造函数->p2构造函数->p2析构函数->p1析构函数。浅拷贝带来的问题是p2对象weight和p1对象的weight指向了同一个位置Q。p2析构函数将p2对象weight指向的位置Q释放了,p1析构函数运行时将p1对象weight指向的位置Q释放,可是Q现在已经不存在了,所以发生错误,这就是浅拷贝带来的问题。

3、深拷贝解决浅拷贝的问题

  • 解决思路:手写拷贝构造函数,在拷贝构造函数中,为*weight通过new重新申请一个堆区内存。这样就不会两个指针指向同一个位置了。
Person()
{
  int age;
  int *weight;
  Person(int n_age,int n_weight)
  {
     age=n_age;
     weight = new int(n_weight);
  }
  //手动书写拷贝构造函数
  Person(const Person &p)
  {
     age=n_age;
     //在拷贝一个对象时,有属性是在堆区内存的,
     //需要写拷贝构造函数
     weight=new int(*p.weight) ;
  }
  ~Person()
  {
     //这里可以写一个析构函数
     if(p.weight!=NULL)
     {
        del weight;
        weight=NULL;
     }
  }
}
void test()
{
  Person p1(10,120);
  cout<<"年龄:"<<p1.age<<"体重:"<<p1.weight<<endl;
  Person p2(p1);
  cout<<"年龄:"<<p2.age<<"体重:"<<p2.weight<<endl;
}
int main()
{
 test();
 return 0;
}

4、扩展
如果写了有参构造函数,那么C++将不产生默认构造函数,但是或有默认的拷贝构造函数。
如果写了拷贝构造函数,那么C++不提供构造函数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值