带参数的拷贝构造函数是用来创建对象时,使用另一个同类对象作为参数进行初始化,将另一个对象内的所有值都复制一套,一般由用户定义编写代码进行复制,这种复制叫做深拷贝,可以将一个对象内的所有数据复制一套,而系统自动处理对象复制的工作叫浅拷贝,区别在于前者由程序员编写代码进行指定复制,后者系统自动复制所有对象内的成员变量值,包括指针,但不负责复制指针指向的内存块中的数据,因为这个开销太大,自动处理会影响效率,所以这项工作交给程序员来决定。
如果fun返回的是对象而不是指针,那么必然fun内部的对象是个局部对象,退出fun时会被释放,因此系统采用了临时对象的措施进行传递对象,系统创建一个临时对象,并调用默认的浅拷贝操作,将局部对象内的成员值复制到临时对象中,假设fun内部的局部对象是L,临时对象是T,这项操作等价于执行以下语句:
student T=L;创建T的时候确实会调用构造函数,但是是默认构造函数也就是student::student(),是无参构造函数。
临时对象由编译器负责管理,所以你感觉不到的,返回后再执行对a赋值,此时,实际上执行的是a=T,所以a=fun(b),实际上对象返回过程a=T=L,也就是复制了2次,浅拷贝时调用的是=操作符重载函数,只是也是默认的,也叫赋值操作符重载。
赋值操作符重载
一个普通变量赋值,比如int a=1;编译器遇到赋值号时会自动处理,将1存入a,但是一个自定义的对象内部的变量是不确定的,为了使对象也能像普通变量那样赋值,系统为对象提供了赋值号(也就是等号)的重载函数,这样2个自定义对象就可以像普通变量那样操作了,实际上系统是遍历对象内的所有变量逐个进行赋值。
这样你代码中,可以这样写:
student a,b;
a=b;
如果没有内置的赋值操作符重载函数,a=b是无法执行的,不过C++也允许你自己编写赋值操作符重载函数。下面就是个赋值操作符重载函数的定义例子,你可以按自己的要求实现特定的功能:
MyClass & MyClass::operator =(MyClass &Obj)
{
//编写特定的处理代码
}