一、语法
返回值类型 operator 运算符(形参表)
{
....
}
二、例题
1:复数类加减法运算重载—成员函数形式
#include <iostream>
using namespace std;
class Complex { //复数类定义
public: //外部接口
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { } //构造函数
Complex operator + (const Complex &c2) const; //运算符+重载成员函数
Complex operator - (const Complex &c2) const; //运算符-重载成员函数
void display() const; //输出复数
private: //私有数据成员
double real; //复数实部
double imag; //复数虚部
};
Complex Complex::operator + (const Complex &c2) const { //重载运算符函数实现
return Complex(real + c2.real, imag + c2.imag); //创建一个临时无名对象作为返回值
}
Complex Complex::operator - (const Complex &c2) const { //重载运算符函数实现
return Complex(real - c2.real, imag - c2.imag); //创建一个临时无名对象作为返回值
}
void Complex::display() const {
cout << "(" << real << ", " << imag << ")" << endl;
}
int main() { //主函数
Complex c1(5, 4), c2(2, 10), c3; //定义复数类的对象
cout << "c1 = "; c1.display();
cout << "c2 = "; c2.display();
c3 = c1 - c2; //使用重载运算符完成复数减法
cout << "c3 = c1 - c2 = "; c3.display();
c3 = c1 + c2; //使用重载运算符完成复数加法
cout << "c3 = c1 + c2 = "; c3.display();
return 0;
}
//c1 = (5, 4)
//c2 = (2, 10)
//c3 = c1 - c2 = (3, -6)
//c3 = c1 + c2 = (7, 14)
2.string重载=
赋值运算符=要求左右两个操作数的类型是匹配的,或至少是兼容的。有时希望=两边的操作数的类型即使不兼容也能够成立,这就需要对=进行重载。C++ 规定,=只能重载为成员函数。
如果没有第 13 行对=
的重载,第 34 行的s = "Good Luck,"
肯定会因为类型不匹配而编译出错。经过重载后,第 34 行等价于s.operator=("Good Luck,");
,就没有问题了。
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char * str;
public:
String() :str(NULL) { }
const char * c_str() const { return str; };
String & operator = (const char * s);
~String();
};
String & String::operator = (const char * s)
//重载"="以使得 obj = "hello"能够成立
{
if (str)
delete[] str;
if (s) { //s不为NULL才会执行拷贝
str = new char[strlen(s) + 1];
strcpy(str, s);
}
else
str = NULL;
return *this;
}
String::~String()
{
if (str)
delete[] str;
};
int main()
{
String s;
s = "Good Luck,"; //等价于 s.operator=("Good Luck,");
cout << s.c_str() << endl;
// String s2 = "hello!"; //这条语句要是不注释掉就会出错
s = "Shenzhou 8!"; //等价于 s.operator=("Shenzhou 8!");
cout << s.c_str() << endl;
return 0;
}
3.前置后置单目运算符
前置单目运算符U,如果要重载 U 为类成员函数,使之能够实现表达式 U oprd,其中 oprd 为A类对象,则 U 应被重载为 A 类的成员函数,无形参。 经重载后, 表达式 U oprd 相当于 oprd.operator U()
后置单目运算符 ++和-- 如果要重载 ++或--为类成员函数,使之能够实现表达式 oprd++ 或 oprd-- ,其中 oprd 为A类对象,则 ++或-- 应被重载为 A 类的成员函数,且具有一个 int 类型形参。 经重载后,表达式 oprd++ 相当于 oprd.operator ++(0)
eg:运算符前置++和后置++重载为时钟类的成员函数。 前置单目运算符,重载函数没有形参,对于后置单目运算符,重载函数需要有一个整型形参。 操作数是时钟类的对象。 实现时间增加1秒钟
//8_2.cpp
#include <iostream>
using namespace std;
class Clock { //时钟类声明定义
public: //外部接口
Clock(int hour = 0, int minute = 0, int second = 0);
void showTime() const;
Clock& operator ++ (); //前置单目运算符重载
Clock operator ++ (int); //后置单目运算符重载
private: //私有数据成员
int hour, minute, second;
};
Clock::Clock(int hour/* = 0 */, int minute/* = 0 */, int second/* = 0 */) { //构造函数
if (0 <= hour && hour < 24 && 0 <= minute && minute < 60 && 0 <= second && second < 60) {
this->hour = hour;
this->minute = minute;
this->second = second;
} else
cout << "Time error!" << endl;
}
void Clock::showTime() const { //显示时间函数
cout << hour << ":" << minute << ":" << second << endl;
}
Clock & Clock::operator ++ () { //前置单目运算符重载函数
second++;
if (second >= 60) {
second -= 60;
minute++;
if (minute >= 60) {
minute -= 60;
hour = (hour + 1) % 24;
}
}
return *this;
}
Clock Clock::operator ++ (int) { //后置单目运算符重载
//注意形参表中的整型参数
Clock old = *this;
++(*this); //调用前置“++”运算符
return old;
}
int main() {
Clock myClock(23, 59, 59);
cout << "First time output: ";
myClock.showTime();
cout << "Show myClock++: ";
(myClock++).showTime();
cout << "Show ++myClock: ";
(++myClock).showTime();
return 0;
}
运行结果:
First time output: 23:59:59
Show myClock++: 23:59:59
Show ++myClock: 0:0:1
前自增调用自增前 后置自增调用自增后
这里前置返回的是引用,如果operator++
返回的是Clock
对象的值而不是引用,那么每次调用++clock
都会创建一个临时对象,该对象随后会被丢弃,而不是修改原始的clock
对象。这会导致只有第一次++
操作生效,后续的调用将不会有任何效果,因为它们是作用于临时对象的。
4.以非成员函数形式重载Complex的加减法运算和“<<”运算符 类外用友元
将+、-(双目)重载为非成员函数,并将其声明为复数类的友元,两个操作数都是复数类的常引用。
将<<(双目)重载为非成员函数,并将其声明为复数类的友元,它的左操作数是std::ostream引用,右操作数为复数类的常引用,返回std::ostream引用,用以支持下面形式的输出: cout << a << b; 该输出调用的是: operator << (operator << (cout, a), b);
//8_3.cpp
#include <iostream>
using namespace std;
class Complex { //复数类定义
public: //外部接口
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { } //构造函数
friend Complex operator + (const Complex &c1, const Complex &c2); //运算符+重载
friend Complex operator - (const Complex &c1, const Complex &c2); //运算符-重载
friend ostream & operator << (ostream &out, const Complex &c); //运算符<<重载
private: //私有数据成员
double real; //复数实部
double imag; //复数虚部
};
Complex operator + (const Complex &c1, const Complex &c2) { //重载运算符函数实现
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
Complex operator - (const Complex &c1, const Complex &c2) { //重载运算符函数实现
return Complex(c1.real - c2.real, c1.imag - c2.imag);
}
ostream & operator << (ostream &out, const Complex &c) { //重载运算符函数实现
out << "(" << c.real << ", " << c.imag << ")";
return out;
}
int main() { //主函数
Complex c1(5, 4), c2(2, 10), c3; //定义复数类的对象
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;
c3 = c1 - c2; //使用重载运算符完成复数减法
cout << "c3 = c1 - c2 = " << c3 << endl;
c3 = c1 + c2; //使用重载运算符完成复数加法
cout << "c3 = c1 + c2 = " << c3 << endl;
return 0;
}