一、拷贝构造函数:用一个已经有的对象构造一个新的对象。函数
CA(const CA & c )函数的名称必须和类名称相一致,它的惟一的一个参数是本类型的一个引用变量,该参数是const 类型,不可变。this
拷贝构造函数何时被用到?spa
(1)当用一个已初始化过的自定义类型对象去初始化另外一个新构造的对象的时候。3d
(2)一个对象以值传递的方式传入。在调用函数时须要将实参对象完整的传递给形参,系统是经过调用拷贝构造函数来实现的,这样能保证形具备和实参彻底相同的值。指针
(3)一个对象以值传递的方式传出函数体。在函数调用完毕将返回值带回函数调用处。此时须要将函数中的对象拷贝到一个临时对象处并传给该函数的调用处。对象
拷贝构造函数为何传引用而不传值?blog
若是拷贝构造函数进行值传递的话,那么形参会产生一个新对象,也就是会调用拷贝构造函数,所以会造成一个死循环。递归
调用拷贝构造函数须要先建立形参对象,建立形参对象又须要调用拷贝构造函数,无限递归确定是不正确的,因此在这里要用引用而不是值传递。内存
二、赋值运算符的重载函数:用一个已经有的对象给一个同一类型的对象赋值。(两个对象都存在)资源
CA & operator = (const CA & )
返回值的对象为引用是为了能够连续赋值
赋值函数中能够既可使用引用也可使用值传递,不过值传递会多生成一个对象,形成资源的浪费。
class A
{
private:
int a;
int b;
public:
A (const A & arg) // 拷贝构造函数
{
a = arg.a;
b = arg.b;
}
A & operator = ( const A & arg) //重载的赋值函数
{
if(this != &arg)// 先判断下是不是自身赋值
{
a = arg.a;
b = arg.b;
}
return *this;
}
};
当类中含有指针成员时,二者的意义有很大区别
复制构造函数需为指针变量分配内存空间,并将实参的值拷贝到其中;而赋值操做符它实现的功能仅仅是将‘=’号右边的值拷贝至左值,在左边对象内存不足时,
先释放而后再申请。固然赋值操做符必须检测是不是自身赋值,如果则直接返回当前对象的引用而不进行赋值操做。
拷贝构造函数分为两类:
深拷贝
class Student{private: char *name;public: Student (const Student & arg) { int length = strlen(arg.name)+1; this->name = new char[length]; // 深拷贝,先在堆上分配内存,再拷贝内容。 strncpy(this->name,arg.name,length); } Student & operator=( const Student &arg) { if(this != &arg) { delete []name;// 先销毁以前分配的堆上的内存 } int length = strlen(arg.name)+1; this->name = new char[length];// 从新分配,并拷贝。 strncpy(this->name,arg.name,length); return *this; }};