基本概念:
重载的运算符是具有特殊名字的函数:它们的名字由关键字 operator 和其后面要定义的运算符号共同组成。 同其他函数一样, 重载的运算符函数也包含返回类型、参数列表以及函数体。
同一个运算符符在不同的上下文有不同的意义。
比如:洗衣服和洗脸是不同的,或者有不同的含义。
C++运算符重载:
(1)不能改变运算符的优先级;
(2)不能改变运算符的结合型;
(3)默认参数不能和重载的运算符一起使用;
(4)不能改变运算符的操作数的个数;
(5)不能创建新的运算符,只有已有运算符可以被重载;
(6)运算符作用于C++内部提供的数据类型时,原来含义保持不变。
改变状态的运算符或者与给定类型密切相关的运算符, 如递增、递减和解引用运算符, 通常是成员。
具有对称性的运算符可能转换任意一端的运算对象, 例如算术、相等性、 关系和位运算符等, 一般都是普通的非成员函数。
运算符重载的方法:
运算符重载的方法是 : 定义一个重载运算符的函数;
在需要执行被重载的运算符时,系统就自动调用该函数,以完成运算;
运算符重载,实质上就是函数的重载!!
运算符重载函数的语法为:
函数类型 operator 运算符(形参表) { 函数体; }
运算符重载为类的友元函数的语法为:
friend 函数类型 operator 运算符(形参表) { 函数体; }
例:实现复数的相加:
class Complex
{
public:
Complex()
{
real = 0;
imag = 0;
}
Complex(double r,double i) : real(r),imag(i) { }
Complex operator+ (Complex &);
void Display();
private:
double real;
double imag;
};
Complex Complex :: operator+ (Complex &c2)
{
Complex temp;
temp.real = real + c2.real;
temp.imag = imag + c2.imag;
return temp;
}
void Complex :: Display()
{
cout << "The complex is : " << real << " + " << imag << "i" << endl;
}
int main()
{
Complex c1(3,4),c2(1.2,-4),c3;
c3 = c1 + c2;
cout << "c1 = " ; c1.Display();
cout << "c2 = " ; c2.Display();
cout << "c1 + c2 = " ; c3.Display();
return 0;
}
运算符重载后,优先级和结合性:
用户重载新定义运算符,不改变原运算符的优先级和结合性。这就是说,对运算符重载不改变运算符的优先级和结合性,并且运算符重载后,也不改变运算符的语法结构,即单目运算符只能重载为单目运算符,双目运算符只能重载双目运算符。
运算符重载时必须遵循哪些原则:
运算符重载可以使程序更加简洁,使表达式更加直观,增加可读性。但是,运算符重载使用不宜过多,否则会带来一定的麻烦。
(1) 重载运算符含义必须清楚。
(2) 重载运算符不能有二义性。
运算符重载函数的两种形式
运算符重载的函数一般地采用如下两种形式:成员函数形式和友元函数形式。这两种形式都可访问类中的私有成员。
注意:
1. 只能对 C++ 中已有的运算符进行重载;
2. 五个不能重载的运算符:
. 成员访问
.* 成员指针访问
:: 域运算符
sizeof 长度运算符
?: 条件运算符
前两个不能重载是为了保证访问成员的功能不被改变;
域运算符和sizeof 运算符的运算对象是类型,而不是变量或一般表达式,不具备重载功能;
3. 重载不能改变运算符运算对象的个数:
即 双目运算符需要两个参数,单目运算符需要一个参数。。
4. 重载不能改变运算符的优先级别;
5. 重载不能改变运算符的结合性:
如:赋值运算符是右向左,重载后不变;
6. 重载运算符函数不能带有默认参数!
7. 重载运算符必须和用户自定义类型的对象一起使用:
其参数至少有一个类对象(或类对象的引用)!!!
即: 不能全部是 C++ 的标准类型!!
一元运算符重载
一元运算符只对一个操作数进行操作,下面是一元运算符的实例:
递增运算符( ++ )和递减运算符( -- )
一元减运算符,即负号( - )
逻辑非运算符( ! )
一元运算符通常出现在它们所操作的对象的左边,比如 !obj、-obj 和 ++obj,但有时它们也可以作为后缀,比如 obj++ 或 obj–。
二元运算符重载
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
返回的又是一个新定义的这个类的对象。
bool operator <(const Distance& d)
{
if(feet < d.feet)
{
return true;
}
if(feet == d.feet && inches < d.inches)
{
return true;
}
return false;
}
这个是重载,比较的是这个类中的成员值,这种操作是你应该明确的。
friend istream &operator>>( istream &input, Distance &D )
{
input >> D.feet >> D.inches;
return input;
}
这个是重载输入字符,看这个模版,这个需要两个操作数。
++ 和 – 运算符重载
Time operator++ ()
{
++minutes; // 对象加 1
if(minutes >= 60)
{
++hours;
minutes -= 60;
}
return Time(hours, minutes);
}
// 重载后缀递增运算符( ++ )
Time operator++( int )
{
// 保存原始值
Time T(hours, minutes);
// 对象加 1
++minutes;
if(minutes >= 60)
{
++hours;
minutes -= 60;
}
// 返回旧的原始值
return T;
}
函数调用运算符
如果类重载了函数调用运算符,则我们可以像使用函数一样使用该类的对象。
一个例子把()重载为求绝对值的符号
#include<bits/stdc++.h>
using namespace std;
class X
{
public:
int operator()(int val)
{
return val<0?-val:val;
}
};
int main()
{
X xObj;
int num=xObj(10);
cout<<"num = "<<num<<endl;
cout<<"Hello World!"<<endl;
return 0;
}
即使xObj是一个类对象,但是我们也能调用该对象。调用对象实际上是在运行重载的调用运算符。
标签:return,函数,运算符,operator,Complex,重载 From: https://blog.51cto.com/u_15952369/6036921