拷贝构造函数和赋值的深入理解

1、什么是拷贝构造函数

拷贝构造函数分为两类:
一类是系统默认提供的拷贝构造函数,只是简单的把栈里面的数据进行拷贝,堆上面的内容没有进行拷贝;
二类是自己定义的拷贝构造函数,能够对堆上面的东西进行深度的拷贝;

2、什么情况下调用拷贝构造函数?

  • 对象声明的时候就初始化(赋值)

public class Student{

private:
	char*name;
	int id;
};

Student a;

Student b=a;//拷贝

  • 以值作为参数传递

void f(Student a)//调用这个函数的时候,会调用拷贝构造函数

  • 以值作为返回值传递

Student f(Student a){

return a;

}

3、浅拷贝和深拷贝的区别?




4、浅拷贝和深拷贝各有什么特点

浅拷贝对于在栈上面的数据进行拷贝是非常好的,而且效率也是非常高的。比如上面的b.id=a.id,这个就是在栈上面的拷贝,

对于在堆上面的拷贝就有点显得不足了,因为在一个对象的生面周期结束的时候,会调用析构函数,而我们会在析构函数里面释放内存(在堆上面分配的)

如果是浅拷贝,先释放a这个对象的时候,我们会把a.name所指的内存释放,此时b.name指的区域就是无效的,等析构b对象的时候,

我们释放b.name所指的内存就会报错,因为那块区域是无效的了,释放无效内存是会报错的。

深拷贝就会解决这个问题,因为a.name和b.name所指的内存是不同的。

拷贝构造函数的一般写法

Student::Student(const Student&student){

int length=strlen(student.name)+1;
this->name=new char[length+1];//这里就是深拷贝,先在堆上面分配内存,然后拷贝内容
strcpy(this->name,student.name);

}

5、什么是赋值操作

对象在申明之后,在进行的赋值运算,我们称之为赋值运算,比如说:

 Student a; Student b;//声明两个对象

a=b;//赋值操作

赋值操作的一般写法

Student& Student::operator=(const Student& student){
if(this==&student){
return *this;//遇到a=a这个种情况
}
if(this->name!=NULL){
delete []name;//释放之前的在堆里面分配的内存
}
int length=strlen(student.name)+1;
this->name=new char[length];
strcpy(this->name,student.name);
this->id=student.id;
return *this;
}

6、比较拷贝构造函数和赋值操作

1、传递参数的形式:都是用传引用的方式,(拷贝构造函数是用引用,详情请点击这里)

2、拷贝构造函数无须释放this->name的内存,这是因为当前对象还没有建立,而赋值操作要释放this->name的内存,那是因为这个对象已经存在于内存上面了。

3、由于调用赋值操作的时候,对象都是建立的了,所以在赋值的时候,我们就检验是否为自己赋值给自己,这样就避免浪费内存。

3、赋值操作返回的是引用,为什么不是值传递或者是指针传递(详情点击这里)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值