1.运算符重载的概念:
可以重新定义已有的运算符,使其完成自定义的功能。
2.运算符重载的作用:
运算符重载与函数重载相似,其目的是增加运算符函数,让运算符具有另一种功能。
3.运算符重载的实质:
因为使用运算符实际就是一种函数调用,所以运算符重载实际上就是函数重载,同函数重载一样属于静态多态性(编译时的多态性,静态绑定,早起联编).
而虚函数属于动态多态性(运行时的多态性,动态绑定,滞后联编).
4.运算符重载的规则:
只能重载已有的且被允许重载的运算符。
重载之后,运算符的优先级和结合性不会改变,也不能够改变。
重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型.
5.运算符的两种重载方式:
当运算符重载为类的成员函数时,函数的参数个数比原来的参与运算的运算数个数要少一个(后缀++、--除外).重载一元运算符没有参数;重载二元运算符只有一个参数。
一般基于某个对象调用成员函数,这个对象是一个隐含的操作数,就是被调用的运算符函数的一个操作数,而且是第一操作数.
当运算符重载为类的友元函数时,参数个数与原运算数的个数相同。
由于友元函数不是成员函数,没有this指针,所以重载二元运算符(双目运算符)时,要有两个参数;重载一元运算符(单目运算符)时,要有一个参数。
注意:
成员函数的调用只能够通过成员函数所属的类的对象来调用,也就是说被重载的运算符的第一操作数的类型是确定的,是隐含的,不可改变。
有些运算符必须用友元函数重载,比如:"<<( 输出运算符 )"和">>( 输入运算符 )"。
6.单目和双目运算符重载的重载:
一般来讲,单目运算符最好重载为成员函数,而双目运算符则最好重载为友元函数。
(1).单目运算符重载:
a.可重载为没有参数的成员函数或者带有一个参数的非成员函数(友元函数),其参数必须是用户定义类型的对象或者是对该对象的引用。
b.单目运算符++和--,重载时,由于有前缀和后缀的差别,其参数个数遵照以下格式规定:
<函数类型> operator ++( ); //前缀运算符重载
<函数类型> operator --( ); //前缀运算符重载
<函数类型> operator ++(int); //后缀运算符重载
<函数类型> operator --(int); //后缀运算符重载
由于前缀++,--时先修改,后使用,所以修改和返回的都是同一个对象.
由于后缀++,--时先使用,后修改,所以带一个参数,创建临时对象来保存对象原来的值.
(2).双目运算符重载:
可以重载为带一个参数的成员函数或者带两个参数的友元函数。
7.几个常用运算符的重载举例:
(1).重载赋值运算符和拷贝构造函数的必要性?
由于系统默认的赋值方式和默认的拷贝构造函数是一种“浅复制”,它将对象数据成员“逐位”进行复制赋值。当类中包含指针成员的时候,它并不会将指针所指向的内存单元的内容复制一份,它只会将指针成员变量的值复制给新对象的指针成员。显然在数据成员有指针的情况下,需要用户自己定义拷贝构造函数和赋值运算符。否则就会造成指针悬挂和野指针问题。
赋值运算符的重载形式:
CPerson &operator=( const CPerson &oCPerson )
{
if (this == &oCPerson) //1、判断是否自己赋值给自己
{
return *this; //是,则返回自己
}
delete m_lpszName; //2、释放自己的内存空间
m_lpszName = NULL; //将其置为NULL是一种好习惯。
m_lpszName = new char[strlen( oCPerson.m_lpszName )+1];
strcpy( m_lpszName, oCPerson.m_lpszName ); //3、复制
delete m_lpszSex; //释放自己的内存空间
m_lpszSex = NULL;
m_lpszSex = new char[strlen( oCPerson.m_lpszSex )+1];
strcpy( m_lpszSex, oCPerson.m_lpszSex ); //复制
return *this; //4、返回赋值后的对象。
}
拷贝构造函数的重载形式:
CPerson( const CPerson &oCPerson )
{
m_lpszName = new char[strlen( oCPerson.m_lpszName )+1];
strcpy( m_lpszName, oCPerson.m_lpszName );
m_lpszSex = new char[strlen( oCPerson.m_lpszSex )+1];
strcpy( m_lpszSex, oCPerson.m_lpszSex );
}
(2).输出运算符(<<)和输入运算符(>>)的重载:
"<<"和">>"只能够用友元函数来重载。
a.输出运算符(<<)的重载:
第一操作数是标准类类型ostream的对象的引用,比如:“&cout”。
第二操作数是本类的对象。为了保证输出运算符(<<)的连用性,重载函数的返回类型应该为ostream的引用。
friend ostream &operator << ( ostream &cout, 类类型 obj );
b.输入运算符(>>)的重载:
第一操作数是标准类类型istream的对象的引用,比如:“&cin”。
第二操作数是本类的对象。
为了保证输入运算符(>>)的连用性,重载函数的返回类型应该为istream的引用。
friend istream &operator >> ( istream &cin, 类类型 &obj );