【C++面向对象程序设计】CH4 运算符重载

本文详细介绍了C++中的运算符重载,包括运算符重载的概念、方法、规则和限制。通过多个示例,如复数加法、字符串比较、自增运算符等,阐述了如何作为成员函数和友元函数来重载运算符。同时,还讲解了重载流插入运算符"<<"和流提取运算符">>"的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、什么是运算符重载

1.定义

2.实质

3.【例4.1】通过成员函数实现复数的加法

二、运算符重载的方法

1.格式

2.规则和限制

(1)规则和限制

(2)两种形式

(3)运算符函数

3.【例4.2】重载运算符,用于两个复数相加

(1)分析

(2)代码&结果

(3)说明

三、重载运算符的规则

四、运算符重载函数作为类成员函数与友元函数

1.【例4.3】将加法运算符重载为适用于复数加法,重载函数作为类的友元函数

​编辑2.【注】

3.书上的错误

五、重载双目运算符

1.含义

2.【例4.4】定义一个字符串类String,用来处理不定长的字符串,重载相等、大于、小于关系运算符,用于两个字符串的等于、大于、小于的比较运算

(1)【分析】

(2)代码&结果

(3)说明

3.扩展到对三个运算符重载:在String类体中声明三个重载函数是友元函数,并编写相应的函数

六、重载单目运算符

1.含义

2.【例4.5】有一个Time类,数据成员有时、分、秒。要求模拟秒表,每次走一秒,满60秒进位,秒又从零开始计数。满60分进位,分又从零开始计数。输出时、分、秒的值

3.【例4.6】在【例4.5】的基础上增加后++运算符重载函数

七、重载流插入运算符和流提取运算符

1.含义

2.重载流插入运算符“<<”

(1)【例4-7】在【例4-2】的基础上用<<重载函数输出复数

(2)说明

3.重载流提取运算符“>>”

(1)【例4.8】在【例4.7】的基础上增加流提取运算符>>重载函数,用cin>>输入复数,用cout输出复数

(2)说明 


一、什么是运算符重载

1.定义

        C++为程序员提供了灵活的手段,让程序员自己定义类,自己设计相应的运算符(必须在已有的运算符基础上设计),使之应用于自己定义的类。与函数重载相似,对已有的运算符赋予新的含义,用一个运算符表示不同功能的运算,这就是运算符重载

        实际上,我们在此之前已经使用了运算符重载。如<<是C++的移位运算符,它又与流对象cout配合作为流插入运算符,这是C++对<<进行了重载处理。

2.实质

        运算符重载是对已有的运算符赋予多重含义。

  • 必要性:C++中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类)
  • 将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参
  • 编译系统对重载运算符的选择,遵循函数重载的选择原则

3.【例4.1】通过成员函数实现复数的加法

#include <iostream>
using namespace std;

class Complex 
{
	private:
		double real;
		double imag;
	public:
		Complex() 
		{
			real = 0;
			imag = 0;
		}
		Complex(double r, double i) 
		{
			real = r;
			imag = i;
		}
		Complex complex_add(Complex &c2);
		void display();
};

Complex Complex::complex_add(Complex &c2) 
{
	Complex c;
	c.real = real + c2.real;
	c.imag = imag + c2.imag;
	return c;
}

void Complex::display() 
{
	cout << "(" << real << "," << imag << "i)" << endl;
}

int main() 
{
	Complex c1(3, 4), c2(5, -10), c3;
	c3 = c1.complex_add(c2);
	cout << "c1=";
	c1.display();
	cout << "c2=";
	c2.display();
	cout << "c1+c2";
	c3.display();
	return 0;
}

  • 在Complex类中定义了complex_add函数做加法,函数的参数是引用对象,作为一个加数。在函数里定义了临时变量c,两个赋值语句相当于:
  • c.real=this->real+c2.real;
  • c.imag=this->imag+c2.imag;
  • 在mian函数中通过对象c1调用加法函数,上面的语句相当于:
  • c.real=c1.real+c2.real;
  • c.imag=c1.imag+c2.imag;

二、运算符重载的方法

1.格式

        运算符重载的方法是定义一个重载运算符函数,在需要时系统自动调用该函数,完成相应的运算。运算符重载实质上是函数的重载。运算符重载函数的格式是:

数据类型 operator 运算符(形参表)

{重载处理}

数据类型:是重载函数值的数据类型

operator是保留字

2.规则和限制

(1)规则和限制

  •  C++中可以重载除下列运算符外的所有运算符:. .* :: ? :
  • 只能重载C++语言中已有的运算符,不可臆造新的
  • 不可改变原运算符的优先级和结合性
  • 不能改变操作数个数
  • 经重载的运算符,其操作数中至少应该有一个是自定义类型

(2)两种形式

  • 重载为类成员函数
  • 重载为友元函数

(3)运算符函数

  • 声明类型

函数类型  operator  运算符(形参)

{

        ...

}

  • 重载为类成员函数时:参数个数=原操作数个数-1(后置++,--除外)
  • 重载为友元函数时:参数个数=原操作数个数,且至少应该有一个自定义类型的形参
  • 不能重载的运算符有五个:.(成员运算符)、.*(成员指针运算符)、::(域运算符)、sizeof(长度运算符)、?:(条件运算符) 
  • 重载函数名是由operator和运算符联合组成
  • 复数加法运算符重载函数原型可以是:

Complex  operator+(Complex &c2);

3.【例4.2】重载运算符,用于两个复数相加

(1)分析

定义一个复数类,用成员函数实现加号的重载函数。两个复数相加结果仍是复数,所以函数的返回值的类型也是复数。用成员函数实现运算符重载函数时,掉用格式是“对象名.成员名”,此时对象就是一个参与运算的操作数,假发还需要另一个操作数,这个操作数用函数的参数传递,参数的类型就是复数类,而运算结果用函数值返回。

(2)代码&结果

#include <iostream>
using namespace std;

class Complex 
{
	public:
		Complex() 
		{
			real = 0;
			imag = 0;
		}
		Complex(double r, double i) 
		{
			real = r;
			imag = i;
		}
		Complex operator +(Complex &c2);
		void display();
	private:
		double real;
		double imag;
};

Complex Complex::operator +(Complex &c2) 
{
	Complex c;
	c.real = real + c2.real;
	c.imag = imag + c2.imag;
	return c;
}

void Complex::display() 
{
	cout << "(" << real << "," << imag << "i)" << endl;
}

int main() 
{
	Complex c1(3, 4), c2(5, -10), c3;
	c3 = c1 + c2;    //直接用+即可
	cout << "c1=";
	c1.display();
	cout << "c2=";
	c2.display();
	cout << "c1+c2=";
	c3.display();
	return 0;
}

(3)说明

  • 用运算符重载函数取代【例4.1】中的加法成员函数,从外观上看函数体和函数返回值都是相通的
  • 在主函数中表达式c3=c1+c2取代了【例4.1】中的c3=c1.complex_add(c2),编译系统将表达式c3=c1+c2解释为c1.operator +(c2),对象c1调用的重载函数operator +,以c2为实参计算两个复数之和
  • 在【例4.2】中能否用一个常量和一个复数相加?如c3=3+c2;(错误)。应该定义对象Complex  c1(3.0,0);c3=c1+c2;
  • 运算符重载后,其原来的功能仍然保留,编译系统根据运算表达式的上下文决定是否调用运算符重载函数。运算符重载和类结合起来,可以在C++中定义使用方便的新数据类型

三、重载运算符的规则

  • C++只允许已有的部分运算符实施重载
  • 不能重载的运算符有五个
  • 重载不改变操作数的个数
  • 重载不改变运算符的优先级
  • 运算符重载函数不能带默认值参数
  • 运算符重载函数必须与自定义类型的对象联合使用,其参数至少有一个类对象或类对象引用
  • C++默认提供=和&运算符重载
  • 运算符重载函数可以是类成员函数,也可以是类的友元函数,还可以是普通函数
  • C++规定赋值运算符、下标运算符、函数调用运算符必须定义为类的成员函数;而输出流插入、输入流提取、类型转换运算符不能定义为类的成员函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值