目录
拷贝构造函数
拷贝构造函数的使用方法
拷贝构造函数与赋值运算符的区别
谈深拷贝和浅拷贝
浅拷贝
注意:
深拷贝
拷贝构造函数
拷贝构造函数的也是一种构造函数,它的作用是将一个类的成员拷贝到另一个类中,类似于赋值。拷贝构造函数分为深拷贝和浅拷贝。
先来定义一个拷贝构造函数(构造函数可以重载),看招:
#include<iostream>
using namespace std;
class date
{
public:
date(int year=0, int month=0, int day=0)
{
_year = year;
_month = month;
_day = day;
}
date(const date& d)//拷贝构造函数
{
this->_year = d._year;
this->_month = d._month;
this->_day = d._day;
}
void print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
将一个类拷贝到另一个类中,自然是需要对应的参数的,参数就是类,这里可以传递指针,引用更好,只是传值形参的话,会造成无限递归。
拷贝构造函数的使用方法
拷贝构造函数的使用:
1.使用();2.使用'=';像这样
拷贝构造函数与赋值运算符的区别
那么拷贝构造函数和赋值运算符有什么区别呢,先来看一段代码对比一下:
int main()
{
date d1(20244, 4, 24);
date d2=d1;
date d3;
d3= d1;//编译器会自动将其转化为d3(d1);
return 0;
}
这里d2采用的拷贝构造函数的方式,d3采用赋值的方式,通过观察,我们可以发现,前者是创造变量时就对类进行了赋值,这个赋值叫做初始化,而后者是先定义好的类,后续赋值,在赋值之前是已经将变量创建好的;
谈深拷贝和浅拷贝
先说浅拷贝
浅拷贝
浅拷贝就是对成员变量进行一一对应赋值,来看一个代码:
#include<iostream>
using namespace std;
class date
{
public:
date(int a=1,int b=1)
{
_a = a;
_b = b;
}
date(const date& d)
{
_a = d._a;//成员变量简单的赋值
_b = d._b;
}
void print()
{
cout << _a << ',' << _b << endl;
}
~date()
{
cout << "~date" << endl;
}
private:
int _a;
int _b;
};
int main()
{
date d1(2,5);
date d2(d1);
d2.print();
return 0;
}
在这个代码中,在对d2进行初始化的时候,是将d1的成员变量对d进行了赋值;最后代码结束存在两次析构,分别是d2和d1的;
注意:
对于简单的成员变量进行简单的复制操作并无大碍,但是如果是指针类型的变量就会出现问题;看代码;
#include<iostream>
using namespace std;
class date
{
public:
date(int b=1)
{
_a =new int[4];
_b = b;
}
date(const date& d)
{
_a = d._a;
_b = d._b;
}
void print()
{
cout << _a << ',' << _b << endl;
}
~date()
{
free(_a);//拷贝后两个成员变量都指向同一块空间,会造成多次析构
cout << "~date" << endl;
}
private:
int* _a;
int _b;
};
int main()
{
date d1(5);
date d2(d1);
d2.print();
return 0;
}
代码中_a为指针类型,初始化是对其进行开辟空间;代码结束对类进行析构,但是问题来了,浅拷贝只是简单的赋值,针对_a来说,d1和d2的_a都指向同一片空间,这就造成了在代码结束时,这片空间会释放两次,就会发生错误,对此就需要进行深拷贝来解决。
深拷贝
#include<iostream>
using namespace std;
class date
{
public:
date(int b=1)
{
_a =new int[4];
_a[0] = 10;
_b = b;
}
date(const date& d)
{
_a = new int[4];
memcpy(_a, d._a, sizeof(int) * 4);//将d2的数据拷贝过来
_b = d._b;
}
void print()
{
cout << _a[0] << ',' << _b << endl;
}
~date()
{
free(_a);
cout << "~date" << endl;
}
private:
int* _a;
int _b;
};
int main()
{
date d1(5);
date d2(d1);
d2.print();
return 0;
}
在拷贝构造的时候对本类的_a也进行开辟空间,然后把另一类的数据利用memcpy拷贝过来就OK了。 这样就不会出现析构多次同一片空间的问题。