<学习笔记>C++运算符重载

一、语法 

返回值类型  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;
}

 

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值