C++支持运算符重载。运算符重载的好处是使得使用类的人更加方便。设计类的人只不过是把设计函数变成了设计运算符重载。因此,运算符重载的本质仍旧是一个函数。
要想使用运算符重载,必须借助关键字operator。
C++对运算符重载是有限制的,其中: . :: ?: * sizeof 这五个运算符是不能被重载的。
运算符重载并不能改变运算符的优先级和结合性。
运算符重载可以分为全局重载和成员函数重载;根据运算符的目数,可以分为单目运算符重载和双目运算符重载。
下面的代码将双目运算符重载为全局函数。
#include<iostream>
class MyComplex
{
private:
double a;
double b;
public:
MyComplex(double x = 0.0,double y = 0.0);
MyComplex(const MyComplex& C);
double getImag()const;
double getReal()const;
void show()const;
};
#include "MyComplex.h"
MyComplex::MyComplex(double x, double y):a(x),b(y)
{
}
MyComplex::MyComplex(const MyComplex& C)
{
this->a = C.a;
this->b = C.b;
}
double MyComplex::getImag()const
{
return this->b;
}
double MyComplex::getReal()const
{
return this->a;
}
void MyComplex::show()const
{
std::cout << a << "+" << b << "i" << std::endl;
}
#include"MyComplex.h"
MyComplex operator+(const MyComplex& c1, const MyComplex& c2);
int main()
{
MyComplex c1(3.3, 2.4);
MyComplex c2(2, 3);
MyComplex c3 = c1 + c2;
MyComplex c4 = operator+(c1, c2); //运算符重载的本质就是函数
c1.show();
c2.show();
c3.show();
c4.show();
return 0;
}
MyComplex operator+(const MyComplex& c1, const MyComplex& c2)
{
//由于a,b是类的私有成员,因此可以这样解决无法访问a,b的问题。
//让类提供一个获取a,b值的接口即可。
MyComplex tmp(c1.getReal() + c2.getReal(), c1.getImag() + c2.getImag());
return tmp;
}#include"MyComplex.h"
MyComplex operator+(const MyComplex& c1, const MyComplex& c2);
int main()
{
MyComplex c1(3.3, 2.4);
MyComplex c2(2, 3);
MyComplex c3 = c1 + c2;
MyComplex c4 = operator+(c1, c2); //运算符重载的本质就是函数
c1.show();
c2.show();
c3.show();
c4.show();
return 0;
}
MyComplex operator+(const MyComplex& c1, const MyComplex& c2)
{
//由于a,b是类的私有成员,因此可以这样解决无法访问a,b的问题。
//让类提供一个获取a,b值的接口即可。
MyComplex tmp(c1.getReal() + c2.getReal(), c1.getImag() + c2.getImag());
return tmp;
}
程序执行结果如下:
可以看到无论是直接使用+还是使用operator+函数来调用,都完成了c1和c2的相加工作。此次的运算符重载使用了类提供的接口获取私有成员的值。更一般的做法是将全局运算符重载声明为类的友元函数。如下:
#include<iostream>
class MyComplex
{
private:
double a;
double b;
//声明友元函数
friend MyComplex operator+(const MyComplex& c1, const MyComplex& c2);
public:
MyComplex(double x = 0.0,double y = 0.0);
MyComplex(const MyComplex& C);
double getImag()const;
double getReal()const;
void show()const;
};
这样我们的运算符重载函数就可以访问类的私有成员了,可以改为如下:
MyComplex operator+(const MyComplex& c1, const MyComplex& c2)
{
MyComplex tmp(c1.a + c2.a, c1.b + c2.b);
return tmp;
}
这就是友元函数经常使用的地方。
#include<iostream>
class MyComplex
{
private:
double a;
double b;
//声明友元函数
//friend MyComplex operator+(const MyComplex& c1, const MyComplex& c2);
public:
MyComplex(double x = 0.0,double y = 0.0);
MyComplex(const MyComplex& C);
double getImag()const;
double getReal()const;
void show()const;
//做为成员函数重载运算符
MyComplex operator+(const MyComplex& c);
};
MyComplex::MyComplex(double x, double y):a(x),b(y)
{
}
MyComplex::MyComplex(const MyComplex& C)
{
this->a = C.a;
this->b = C.b;
}
double MyComplex::getImag()const
{
return this->b;
}
double MyComplex::getReal()const
{
return this->a;
}
void MyComplex::show()const
{
std::cout << a << "+" << b << "i" << std::endl;
}
MyComplex MyComplex::operator+(const MyComplex& c)
{
MyComplex tmp(this->a + c.a, this->b + c.b);
return tmp;
}
#include"MyComplex.h"
//MyComplex operator+(const MyComplex& c1, const MyComplex& c2);
int main()
{
MyComplex c1(3.3, 2.4);
MyComplex c2(2, 3);
MyComplex c3 = c1 + c2;
MyComplex c4 = c1.operator+(c2); //运算符重载的本质就是函数
c1.show();
c2.show();
c3.show();
c4.show();
return 0;
}
//全局双目运算符重载
//MyComplex operator+(const MyComplex& c1, const MyComplex& c2)
//{
// //由于a,b是类的私有成员,因此可以这样解决无法访问a,b的问题。
// //让类提供一个获取a,b值的接口即可。
// //MyComplex tmp(c1.getReal() + c2.getReal(), c1.getImag() + c2.getImag());
// //return tmp;
// MyComplex tmp(c1.a + c2.a, c1.b + c2.b);
// return tmp;
//}
运行结果如下:
作为成员函数重载运算符的时候,由于成员函数含有this指针。所以我们只传递一个参数就够了。
单目运算符只有一个操作数。他的重载比较复杂。首先在类内声明友元函数。注意必须传递引用才能实现单目得效果。
friend MyComplex& operator++(MyComplex& c);
然后实现如下:
MyComplex& operator++(MyComplex& c)
{
//要保证先自增,再被使用
c.a++;
c.b++;
return c;
}
MyComplex& MyComplex::operator++()
{
this->a++;
this->b++;
return *this;
}
后置++得函数原型和前置++不一样,否则编译器将认为这是一个函数的重定义。出于这一点考虑,C++要求后置运算符重载含有一个占位参数。这个参数什么用都没有,只是为了让编译器确定这是后置运算符。
friend MyComplex operator++(MyComplex& c, int);
MyComplex operator++(MyComplex& c, int)
{
//返回的是值,不是引用。
MyComplex tmp(c);
c.a++;
c.b++;
return tmp;
}
MyComplex MyComplex::operator++(int)
{
MyComplex tmp(*this);
this->a++;
this->b++;
return tmp;
}
下面给出所有的代码:
//头文件
#pragma once
#include<iostream>
class MyComplex
{
private:
double a;
double b;
//声明友元函数
//friend MyComplex operator+(const MyComplex& c1, const MyComplex& c2);
//重载前置++
//friend MyComplex& operator++(MyComplex& c);
//重载后置++
//friend MyComplex operator++(MyComplex& c, int);
public:
MyComplex(double x = 0.0,double y = 0.0);
MyComplex(const MyComplex& C);
double getImag()const;
double getReal()const;
void show()const;
//做为成员函数重载运算符
MyComplex operator+(const MyComplex& c);
//前置++重载
MyComplex& operator++();
//后置++重载
MyComplex operator++(int);
};
//MyComplex.cpp
#include "MyComplex.h"
MyComplex::MyComplex(double x, double y):a(x),b(y)
{
}
MyComplex::MyComplex(const MyComplex& C)
{
this->a = C.a;
this->b = C.b;
}
double MyComplex::getImag()const
{
return this->b;
}
double MyComplex::getReal()const
{
return this->a;
}
void MyComplex::show()const
{
std::cout << a << "+" << b << "i" << std::endl;
}
MyComplex MyComplex::operator+(const MyComplex& c)
{
MyComplex tmp(this->a + c.a, this->b + c.b);
return tmp;
}
MyComplex& MyComplex::operator++()
{
this->a++;
this->b++;
return *this;
}
MyComplex MyComplex::operator++(int)
{
MyComplex tmp(*this);
this->a++;
this->b++;
return tmp;
}
//main.cpp
#include"MyComplex.h"
//MyComplex operator+(const MyComplex& c1, const MyComplex& c2);
//MyComplex& operator++(MyComplex& c);
//MyComplex operator++(MyComplex& c, int);
int main()
{
MyComplex c1(3.3, 2.4);
MyComplex c2(2, 3);
MyComplex c3 = c1 + c2;
MyComplex c4 = c1.operator+(c2); //运算符重载的本质就是函数
(++c2).show();
c2++.show();
//c1.show();
//c2.show();
//c3.show();
//c4.show();
return 0;
}
//全局双目运算符重载
//MyComplex operator+(const MyComplex& c1, const MyComplex& c2)
//{
// //由于a,b是类的私有成员,因此可以这样解决无法访问a,b的问题。
// //让类提供一个获取a,b值的接口即可。
// //MyComplex tmp(c1.getReal() + c2.getReal(), c1.getImag() + c2.getImag());
// //return tmp;
// MyComplex tmp(c1.a + c2.a, c1.b + c2.b);
// return tmp;
//}
//MyComplex& operator++(MyComplex& c)
//{
////保证先自增,在使用。
// c.a++;
// c.b++;
// return c;
//}
//MyComplex operator++(MyComplex& c, int)
//{
// MyComplex tmp(c);
// c.a++;
// c.b++;
// return tmp;
//}