前言
C++预定义的运算符只适用于基本数据类型。为了解决一些实际问题,可能需要定义一些新类型即自定义类型,然而 C++不允许生成新的运算符,因此为了实现对自定义类型的操作,就必须自己来编写程序说明某个运算符如何作用于这些数据类型,这样的程序可读性较差。针对这种情况,C++允许重载现有的大多数运算符,即允许给已有的运算符赋予新的含义,从而提高了 C++的可扩展性,针对同样的操作,使用重载运算符比函数的显式调用更能提高程序的可读性。
运算符重载规定
只能重载 C++中原先已定义的运算符。不能自己“创造”新的运符进行重载
并不是所有的运算符都可以进行重载。不能进行重载的运算符有 .* :: ?: # .
运算符重载的语法
返回值类型 operator运算符(形参列表)
{
//...
}
下面是一个示例
#include<iostream>
using namespace std;
class Complex
{
public:
double real, image;
Complex(double r = 0.0, double i = 0.0) :real(r), image(i) {};
Complex operator+(const Complex& c);
void Print();
};
Complex operator-(Complex& a, Complex& b)
{
return Complex(a.real - b.real, a.image - b.image);
}
Complex Complex::operator+(const Complex& a)
{
return Complex(a.real + real , a.image + image);
}
void Complex::Print()
{
if (image > 0)
cout << real << "+" << image << "i" << endl;
else
cout << real << image << "i" << endl;
}
int main()
{
Complex c1(2.3, 3.4);
Complex c2(2.1, 2.3);
Complex c3;
Complex c4;
c3 = c1 + c2;
c3.Print();
c4 = c2 - c1;
c4.Print();
return 0;
}
重载单目运算符
#include<iostream>
using namespace std;
class Object
{
public:
int i;
Object(int x) :i(x) {};
void Print()
{
cout << i << endl;
}
Object operator+()
{
i = -i;
return *this;
}
};
void test1()
{
Object obj1(1,2);
//显示调用
obj1 = obj1.operator-();
//隐式调用
//obj1 = -obj1;
obj1.Print();
return 0;
}
重载双目运算符
Object operator+(Object obj)
{
i = i + obj.i;
j = j + obj.j;
return *this;
}
void test2()
{
Object obj1(1,2);
Object obj2(3, 4);
obj1 = obj1 + obj2;
obj1.Print();
}
重载++,--运算符
前置++
Object operator++() //前置
{
++i;
++j;
return *this;
}
void test3()
{
Object obj1(1, 2);
Object obj;
obj=++obj1;
obj.Print();
}
后置++
Object operator++(int)
{
Object temp = *this;
i++;
j++;
return temp;
}
void test3()
{
Object obj1(1, 2);
Object obj;
obj = obj1++;
obj.Print();
}
重载赋值运算符
在C++之深拷贝和浅拷贝提到,这里不做过多赘述
仿函数
重载()
#include<iostream>
using namespace std;
class Add_Int
{
private:
int value;
public:
Add_Int(int x = 0) :value(x) {}
~Add_Int() {}
public:
//int operator()(Add_Int * const this,int x,int y)
inline int operator()(int x, int y)
{
value = x + y;
return value;
}
};
int main()
{
Add_Int add;
//隐式调用
int x = add(10, 20);
//显示调用
int y = add.operator()(10, 20);
// y = operator()(&add,10,20); //正确
// y = operator(&add)(10,20); //错误,因为这里的()是函数名
x = Add_Int(0)(12, 23);//类型名后面加()意味着构建对象,拿对象调动()重载
cout << x << endl;
}
友元函数重载运算符
friend <函数类型>operator<运算符>(形参1,[形参2])
{
..
}
成员函数与友元函数重载运算符的比较
在进行运算符重载时,既可以用成员函数重载,也可以用友元函数重载。下面是这两种方式成员函数重载运算符的比较。
对于双目运算符,用成员函数重载时参数表中有一个参数,而用友元函数重载时参数表中有两个参数:对于单目运算符,用成员函数重载时参数表中没有参数,而用友元函数重载时参数表中有一个参数。
对双目运算符一般可以用友元函数重载或用成员函数重载,下面的情况必须使用友元函数重载