为什么要对运算符进行重载 ?
C++ 预定义中的运算符的操作对象 只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对运算符进行重新定义,赋予其新的功能,以满足自身的需求。
C++运算符重载的实质:
运算符重载的实质就是 函数重载或函数多态。运算符重载是一种形式的C++多态。目的在于让人能够用同名的函数来完成不同的基本操作。
运算符重载格式:
要重载运算符,需要使用被称为运算符函数的特殊函数形式。
<返回类型说明符> operator <运算符符号> ( <参数表> )
{
<函数体>
}
运算符重载的规则:
也就是说不能对基本数据类型进行重载,这会破坏原有的运算规则。
例如:
int index;
%index;这种是不被允许的。
= 赋值运算符,
() 数调用运算符,
[ ] 下标运算符,
-> 通过指针访问类成员的运算符。
重载运算符有两种方式,即:
重载为类的成员函数 || 重载为类的非成员函数。
对于成员函数来说,一个操作数通过 this 指针隐式的传递,(即本身),另一个操作数作为函数的参数显示的传递;对于友元函数(非成员函数)两个操作数都是通过参数来传递的。
两者有何区别 ? 先上一段代码:
include <iostream>
using namespace std;
class Test{
public:
Test(int para_x = 0):m_x(para_x){}; //构造函数
Test operator + (const Test & B) const
{
Test obj;
obj = this->m_x + B.m_x;//this指针可以省略
return obj;
}
private:
int m_x;
};
int main()
{
Test A(5),C;
C = A + 3;
return 0;
}
代码非常简单且正常运行,却足以说明问题。
C = A + 5; 可以写作 C = A.(5);
由 A 来调用 operator + 函数,而 5 则被构造成一个 Test 对象,这个构造过程就是隐式转换。(我们看不见,但是编译器这样做)
如果代码中是 C = 5 + A; 那么编译是不通过的,因为 5 可没有所谓的成员函数。
假如你想让这条语句编译通过,该如何做?
将这条语句解释为 C = operator+(5, A);不再使用 this 指针。通过非成员函数来实现操作符重载。
Test operator + (const Test & A,const Test & B) const
还有一个问题,既然是非成员函数,那么是作为普通成员函数,还是应该写作友元函数
对于类的非成员函数,通常我们都将其声明为友元函数,因为大多数时候重载运算符要访问类的私有数据,
当然也可以设置为非友元非类的成员函数。但是非友元又不是类的成员函数是没有办法直接访问类的私有数据的,就得通过在此函数中调用类的公有函数来访问私有数据会降低性能。
成员函数与非成员函数最大的区别在于是否有 this 指针。
小结:
T1 = T2 + T3; 可以解释为T1 = T2.operator+(T3); //成员函数
也可以解释为T1 = operator+(T2,T3);//非成员函数
C++ 能够使用流提取运算符 >> 和流插入运算符 << 来输入和输出内置的数据类型。
我们可以重载流提取运算符和流插入运算符来操作对象等用户自定义的数据类型。
#include
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
Distance(){feet = 0;inches = 0;}
Distance(int f, int i){feet = f;inches = i;}
friend ostream &operator<<( ostream &output, const Distance &D )
{
output << "F : " << D.feet << " I : " << D.inches;
return output;
}
friend istream &operator>>( istream &input, Distance &D )
{
input >> D.feet >> D.inches;
return input;
}
};
int main()
{
Distance D1;
cout << "Enter the value of object : " << endl;
cin >> D1;
cout << "First Distance : " << D1 << endl;
return 0;
}
ClassName operator++ () // 重载前缀递增运算符( ++ )
ClassName operator++( int ) // 重载后缀递增运算符( ++ )
类似地,也可以写出重载递减运算符( – )。
下标运算符重载看起啦有些奇怪,其实我们是经常使用的。
string str(“hello,world”);
cout << str[0] << endl;
#include
using namespace std;
const int SIZE = 10;
class safearay
{
private:
int arr[SIZE];
public:
safearay()
{
register int i;
for(i = 0; i < SIZE; i++){arr[i] = i;}
}
int operator[](int i)
{
if( i > SIZE )
{
cout << "Index out of bounds" <<endl;
return -1;
}
return arr[i];
}
};
int main()
{
safearay A;
cout << "Value of A[2] : " << A[2] <<endl;
cout << "Value of A[5] : " << A[5]<<endl;
cout << "Value of A[12] : " << A[12]<<endl;
return 0;
}