一、构造函数
(一)复制构造函数(深拷贝和浅拷贝)
1、构造拷贝函数:用一个已有的对象,构造和它同类型的副本;
class xxx { xxx (const xxx &that) {...} };
&that是引用,拷贝构造函数推荐使用引用,如果直接传递值,那么会导致无限递归;
2 、如果一个类没有定义拷贝构造函数,系统会提供一个缺省拷贝构造函数:值的简单复制
缺省拷贝构造函数对于基本类型的成员变量,按字节复制;
对于类类型成员变量,调用相应类型的拷贝构造函数
3、 在某些情况下,缺省拷贝构造函数只能实现浅拷贝,如果需要获得深拷贝的复制效果,就需要自己定义拷贝构造函数;
一般下面两种情况需要自定义拷贝构造函数:
如果成员里面包含指针或者引用;
如果成员对象指向 new 地址;
拷贝函数被调用的情况有:
1,定义新对象,并用已有对象初始化新对象时; 即执行语句“CExample B=A; ” 时(定义对象时使用赋值初始化);
2,当对象直接作为参数传给函数时,函数将建立对象的临时拷贝,这个拷贝过程也将调同拷贝构造函数。
例如:
BOOL testfunc(CExample obj)
{
//针对obj的操作实际上是针对复制后的临时拷贝进行的
}
testfunc(theObjone); //对象直接作为参数,拷贝函数将被调用;
3,当函数中的局部对象被返回给函数调者时,也将建立此局部对象的一个临时拷贝,拷贝构造函数也将被调用 ;
例如:
CTest func()
{
CTest theTest;
return theTest
}
(二)复制赋值运算符函数
1、为什么要对=赋值操作符进行重载?
答:接上面的例子,用户在使用语句ObjB = ObjA的时候,或许ObjB的pStr已经指向了动态申请的空间,如果直接简单将其指向的地址覆盖,就会导致内存泄露,所以需要对=赋值操作符进行重载,在重载函数中判断pStr如果已经指向了动态申请的空间,就先将其释放。
2、拷贝构造函数和=赋值操作符重载的关系。
答:从原文的例子中可以看出,=赋值操作符重载比拷贝构造函数做得要多,它除了完成拷贝构造函数所完成的拷贝动态申请的内存的数据之外,还释放了原本自己申请的内存空间。所以原文最后给出的拷贝构造函数的实现可以使用=赋值操作符的重载来完成。
转载网址:https://blog.youkuaiyun.com/gxtdjh/article/details/6653499
(三)临时对象的构造函数(???)
二、运算符重载
运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进行的操作。运算符函数的定义与其他函数的定义类似,惟一的区别是运算符函数的函数名是由关键字 operator 和其后要重载的运算符符号构成的。运算符函数定义的一般格式如下:






运算符重载时要遵循以下规则:











运算符函数重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数。非成员函数通常是友元。(可以把一个运算符作为一个非成员、非友元函数重载。但是,这样的运算符函数访问类的私有和保护成员时,必须使用类的公有接口中提供的设置数据和读取数据的函数,调用这些函数时会降低性能。可以内联这些函数以提高性能。)
成员函数运算符









当运算符重载为类的成员函数时,函数的参数个数比原来的操作数要少一个(后置单目运算符除外),这是因为成员函数用this指针隐式地访问了类的一个对象,它充当了运算符函数最左边的操作数。因此:















友元函数运算符









当运算符重载为类的友元函数时,由于没有隐含的this指针,因此操作数的个数没有变化,所有的操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。









两种重载形式的比较
在多数情况下,将运算符重载为类的成员函数和类的友元函数都是可以的。但成员函数运算符与友元函数运算符也具有各自的一些特点:













转载网址:https://blog.youkuaiyun.com/zgl_dm/article/details/1767201