拷贝构造函数作用:用一个已存在的对象来初始化一个正在创建的新对象。拷贝构造函数有以下特征:
- 拷贝构造函数名与类名相同,形参只有一个,是对象的引用,所以不能重载拷贝构造函数,拷贝构造函数原形为:<类名>(<类名>&对象名);
- 拷贝构造函数无任何函数返回类型说明;
- 若类声明中无拷贝构造函数,系统会自动给出一个默认的拷贝构造函数,该拷贝构造函数只进行对象数据成员间的对位拷贝,即所谓的“浅拷贝”;
- 某些情况下,用户必须在类定义中给出一个显示的拷贝构造函数,以实现用户指定的用一个对象初始化另一个对象的功能,即所谓的“深拷贝”;
- 以下三种情况,系统会自动调用拷贝构造函数:
(1)当使用下面的声明语句,用一个已存在的对象初始化一个新对象时,系统会自动调用拷贝构造函数:
<类名><新对象名>(<已存在对象名>);
或 <类名><新对象名>=<已存在对象名>;
(2)对象作为实参,在函数调用开始进行实参和形参结合时,会自动调用拷贝构造函数,完成由已知的实参对象初始化形参新对象的功能;
(3)如果函数的返回值是类的对象,在函数调用完成返回时,系统自动调用拷贝构造函数,用return后面的已知对象来初始化一个临时新对象(所创建的临时对象只在外部表达式范围内有效,表达式结束时,系统将自动调用析构函数撤销该临时对象)。
**例如:**在主函数中需要用一个已知的IntArray类对象来初始化一个新的IntArray类对象,直接用系统提供的默认拷贝构造函数会出现问题(两个对象指向一个内存空间,系统回收内存空间时会出现报错)以及解决方法如下:
#include<iostream>
using namespace std;
class IntArray
{
public:
IntArray(int sz)
{
m_size=sz;
m_ptr=new int[sz];
}
IntArray()
{
m_size=10;
m_ptr=new int[m_size];
}
void displayArraySize()
{
cout<<"The size is:"<<m_size<<endl;
}
~IntArray()
{
cout<<"Destructing Array with size:"<<m_size<<endl;
delete []m_ptr;//收回额外空间
}
IntArray(IntArray &x) //拷贝构造函数
{
m_size=x.m_size;
m_ptr=new int[m_size];
}
private:
int m_size;
int *m_ptr;
//整型指针在用之前需要给他分配一个内存空间,分配内存空间之后把 分配内存空间首地址赋给m_ptr
};
int main(){
IntArray x(20);
IntArray y(x);//调用系统默认的拷贝构造函数, 用已存在对象x初始化y
x.displayArraySize();
y.displayArraySize();
return 0;
}
关于上述程序的理解:
1、浅拷贝的内存空间只有一个,在y中被析构函数销毁后继续释放X的内存空间就会出现错误 。
2、如果一个类中没有指针成员变量的话,一般用浅拷贝就可以了,如果一个类中有指针成员变量的话,一般需要定义一个拷贝构造函数实现深拷贝 。