1. 拷贝构造函数
什么时候会调用拷贝构造函数 ?
使用一个已经创建好的对象来初始化一个新的对象。
Student mya("zhang3",22);
//如果是在定义一个对象通过另一个对象来初始化,那么会调用拷贝构造函数
Student myb(mya);
//等同于Student myb = mya;
特点: 值传递的方式给函数参数传值
代码示例如下:
class Student{
public:
Student()
{
cout<<Student()<<endl;
}
Student(char *name,int age){
this->name = new char[256];
strcpy(this->name,name);
this->age = age;
cout<<Student(char *name,int age)<<endl;
}
//如果我们没有自己定义拷贝构造函数,编译器就会帮助我们自动生成默认的拷贝构造函数---浅拷贝--值的拷贝
// Student(Student &other) //Student &other = mya
// {
// this->name = other.name;
// this->age = other.age;
// cout<<Student(Student &other)<<endl;
// }
//自定义深拷贝 --在进行值的拷贝的同时,也要给指针变量申请新的堆空间
Student(const Student &other) //Student &other = mya
{
//申请堆空间
this->name = new char[256];
//值的拷贝
strcpy(this->name,other.name);
this->age = other.age;
cout<<Student(Student &other)<<endl;
}
~Student(){
//析构函数一般用来 释放 成员的内存空间
delete []name;
cout<<~ Student()<<endl;
}
void show()
{
cout<<this->name<< <<this->age<<endl;
}
private:
char *name;
int age;
};
int main()
{
Student mya("zhang3",22);
//如果是在定义一个对象通过另一个对象来初始化,那么会调用拷贝构造函数
Student myb(mya);
//Student myb = mya;
return 0;
}
2. 赋值函数
当一个类的对象对另一个对象进行直接赋值时会调用赋值函数
Data mya;
mya.setName("zhangsan");
Data myb;
//赋值重载
myb = mya; //编译器会转换成 myb.operator=(mya)
如果程序员没有自定义赋值运算符函数。系统会调用自动生成的默认赋值函数(如下面代码注释部分)
什么时候需要自定义赋值函数?
如果类定义中存在指针或者引用变量或对象,对象与对象进行赋值时就会出现内存泄漏。
为了防止这种情况发生我们就需要自定义赋值函数。
(我的理解就是 -> 当申请了堆空间的时候 )
代码示例如下
class Data
{
public:
Data(){
name = new char[256];
}
~Data(){
delete[]this->name;
}
void setName(const char *name) {
strcpy(this->name,name);
}
/*
//如果没有自定义赋值函数,系统执行自动生成的默认赋值函数 ---(系统自动生成的赋值函数底层原型)
void operator=(Data &ra) //Data &ra = mya
{
this->name = ra.name;
} */
//系统调用默认的赋值函数会造成内存泄漏 /所以我们需要只需要自定义赋值函数
void operator=(Data &ra) //Data &ra = mya
{
strcpy(this->name, ra.name);
}
private:
char * name; //姓名
};
int main()
{
Data mya;
mya.setName("zhangsan");
Data myb;
//赋值重载
myb = mya; //编译器会转换成 myb.operator=(mya)
return 0;
}
总结:
当我们对两者不够了解时,很容易错写,错用。
拷贝构造函数就是在对象被创建的时候调用的,而赋值函数只能被创建好的对象调用