运算符重载
运算符重载 实质是函数重载,在实现过程中,
首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参。
然后根据实参的类型来确定需要调用的函数。
特点:
这个过程是在编译过程中完成的。
重载之后运算符的优先级和结合性都不会改变。
重载的功能应当与原有功能相类似。
当运算符重载为类的成员函数时,函数的参数个数比原来的运算数个数要少一个(后缀++、--除外);当重载为类的友元函数时,参数个数与原运算数的个数相同。
一般来讲,单目运算符最好重载为成员函数,而双目运算符则最好重载为友元函数。
运算符重载的主要优点就是允许改变使用于系统内部的运算符的操作方式,以适应用户新定义类型的类似运算。
单目运算指运算所需变量为一个的运算符,即在运算当中只有一个操作数,又叫一元运算符,运算符包括赋值运算符、算术运算符、逻辑运算符、位逻辑运算符、位移运算符、关系运算符、自增自减运算符。
双目运算符是值运算所需变量为两个的运算符,例如+,-,*,/,%,<,>,>=,<=,==,!=,<<,>>,&,^,|,&&,||,=
运算所需变量为三个的运算符叫做三目运算符,只有条件表达式【?:】
类型转换运算符【(类型)】、指针运算符和取地址运算符【*和&】、长度运算符【sizeof】
运算符重载的实现
运算符的重载形式有两种:重载为类的成员函数和重载为类的友元函数。
运算符重载为类的成员函数的语法形式如下:
<函数类型> operator <运算符>(<形参表>)
{
<函数体>;
}
friend <函数类型> operator <运算符>(<形参表>)
{
<函数体>;
}
单目运算符重载
<函数类型> operator ++(); //前缀运算
<函数类型> operator ++(int); //后缀运算
Complex operator - () {
this->_x = -this->_x;
this->_y = -this->_y;
return *this;
}
Complex& operator ++ (){
++ this->_x;
++ this->_y;
return *this;
}
Complex operator ++ (int){
Complex temp; // 创建临时的对象,存放原来的对象
temp.x = this->_x ++;
temp.y = this->_y ++;
return temp;
}
双目运算符重载
对于双目运算符,一个运算数是对象本身的数据,由this指针给出。
Complex operator - (Complex &arg) {
Complex temp;
temp._x = this->_x - arg._x;
temp._y = this->_y - arg._y;
return temp; ;
}
-> 运算符重载
“->”运算符是成员访问运算符,这种一元的运算符只能被重载为成员函数,所以也决定了它不能定义任何参数。一般成员访问运算符的典型用法是:
对象->成员,基本不耗时间。
成员访问运算符“->”函数重载的一般形式为:
type class_name::operator->(); // 耗时间,尽量不要使用。
赋值运算符重载
在C++中有两种类型的赋值运算符:
一类是“+=”和“-=”等先计算后赋值的运算符。
一类是“=”即直接赋值的运算符, 建议都重载,效率比编译器生成的高。
注意:
直接赋值,如果一个类包含指针成员,采用这种默认的按成员赋值,那么当这些成员撤消后,内存的使用将变得不可靠
Sample &operator = (Sample &s)
{
delete p;
p=new char[strlen(s.p)+1];
strcpy(p,s.p);
return *this;
}
下标运算符重载
下标运算符重载函数只能作为类的成员函数,不能作为类的友元函数。
下标运算符“[ ]”函数重载的一般形式为:
type class_name::operator[ ](arg_);
其中arg为该重载函数的参数。重载了的下标运算符只能且必须带一个参数,该参数给出下标的值。重载函数operator[ ]的返回值类型type是引用类型。
运算符new 和 delete 重载
new和delete只能被重载为类的成员函数,不能重载为友元。而且,无论是否使用关键字static进行修饰,重载了的new和delete均为类的静态成员函数, 建议自己重载。
运算符new重载的一般形式为:
void *class_name::operator new(size_t,<arg_list>);
new重载应返回一个无值型的指针,且至少有一个类型为size_t的参数。若该重载带有多于一个的参数,则其第一个参数的类型必须为size_t。
运算符delete重载的一般形式为:
void *class_name::operator delete(void *,<size_t>);
delete重载应返回一个无值型的指针,且至少有一个类型为无值型指针的参数。该重载最多可以带有两个参数,若有第二个参数,则其第二个参数的类型必须为size_t。
逗号运算符重载
逗号运算符是双目运算符,和其他运算符一样,也可以通过重载逗号运算符来完成期望完成的工作。逗号运算符构成的表达式为“左运算数,右运算数”,该表达式返回右运算数的值。如果用类的成员函数来重载逗号运算符,则只带一个右运算数,而左运算数由指针this提供。
类型转换运算符重载
不稳定,不建议使用
类型转换运算符重载函数的格式如下:
operator <类型名>()
{
<函数体>;
}
与以前的重载运算符函数不同的是,类型转换运算符重载函数没有返回类型,因为<类型名>就代表了它的返回类型,而且也没有任何参数。在调用过程中要带一个对象实参。
实际上,类型转换运算符将对象转换成类型名规定的类型。转换时的形式就像强制转换一样。如果没有转换运算符定义,直接用强制转换是不行的,因为强制转换只能对标准数据类型进行操作,对类类型的操作是没有定义的。