06 运算符重载

文章介绍了C++中的运算符重载概念,通过MyComplex复数类展示了如何重载+运算符,强调了返回值为常量引用的原因。同时提到了>>和<<运算符的重载通常作为友元函数来实现,以避免修改类的私有数据。此外,文章还讨论了运算符重载的一些规则,如不能改变优先级和结合性,以及不能有默认参数。

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

运算符重载

学习目的:

​ 掌握运算符重载规则 能够自主实现运算符重载

​ 通过重载运算符,扩展运算符功能

内容:

​ 基础语法(**) 规则详细了解

​ 重载 >> 和 << 注意事项(**)

基础语法

重载的概念:重新赋予含义或内容。

运算符重载实质上就是定义一个新的函数,去赋予运算符一个新的功能或规则。

#include <iostream>
using namespace std;


class MyComplex
{
public:
	MyComplex(double real = 0.0, double imag = 0.0);
	~MyComplex();
	void display() const;
	// 返回值类型 函数名(形参列表){}
	// 函数名:operator运算符名称
	/*MyComplex operator+(MyComplex other)
	{
		MyComplex obj;
		obj.m_real = this->m_real + other.m_real;
		obj.m_imag = this->m_imag + other.m_imag;
		return obj;
	}*/
	const MyComplex & operator+(const MyComplex& other) const ;


private:
	double m_real;
	double m_imag;

};

MyComplex::MyComplex(double real, double imag)
: m_real(real), m_imag(imag)
{
}

void MyComplex::display() const
{
	cout << "(" << m_real << '+' << m_imag << 'i' << ')' << endl;
}

// 如果去掉 返回值中的 const 则会报: 非常量引用的初始值必须为一左值;
// 表面: 函数体中 return 后面的表达式是一个常量(参数传进来的时候就是常量)。
 const MyComplex& MyComplex::operator+(const MyComplex& other) const
{
	// 创建了一个没有名字的临时对象(代码报错,修改为下列代码)
	 return MyComplex(this->m_real + other.m_real, this->m_imag + other.m_imag);
	/*MyComplex obj;
	obj = MyComplex(this->m_real + other.m_real, this->m_imag + other.m_imag);
	return obj;*/
}
// 注:使用引用的好处是避免多次调用拷贝构造函数

MyComplex::~MyComplex()
{
}


int	main()
{
	MyComplex obj_1(3, 5);
	obj_1.display();

	MyComplex obj_2(4, 6);
	obj_2.display();

	MyComplex obj_3;
	obj_3 = obj_1 + obj_2;
	obj_3.display();

	// obj_1 + obj_2;

	return 0;
}


注:1. 返回值为引用类型时,暂未完全搞明内部逻辑(引用可理解为一个常量指向的指针,当作变量去用。);

​ 2. 拷贝构造函数的理解还需进一步学习;

​ 3. 创建一个无名临时对象能否被引用变量接收??(MyComplex & MyComplex::operator+(const MyComplex& other) const 函数体中注释部分报错。)(注释中已针对该问题进行修改,错误排除。——>paper tiger !)


全局函数示例:

#include <iostream>
using namespace std;


class MyComplex
{
public:
	MyComplex(double real = 0.0, double imag = 0.0);
	~MyComplex();
	void display() const;
	// 声明为友元函数
	friend MyComplex & operator+(const MyComplex & obj1, const MyComplex & obj2);


private:
	double m_real;
	double m_imag;

};

// 定义为全局函数,对于 私有成员 的使用需声明为该类的友元函数
MyComplex & operator+(const MyComplex & obj1, const MyComplex & obj2);


int	main()
{
	MyComplex obj_1(3, 5);
	obj_1.display();

	MyComplex obj_2(4, 6);
	obj_2.display();

	MyComplex obj_3;
	obj_3 = obj_1 + obj_2;
	obj_3.display();

	// obj_1 + obj_2;



	return 0;
}

MyComplex & operator+(const MyComplex & obj1, const MyComplex & obj2)
{

	MyComplex obj;
	obj = MyComplex(obj1.m_real + obj2.m_real, obj1.m_imag + obj2.m_imag);
	return obj;
}

/** MyComplex **/
MyComplex::MyComplex(double real, double imag)
	: m_real(real), m_imag(imag)
{
}

void MyComplex::display() const
{
	cout << "(" << m_real << '+' << m_imag << 'i' << ')' << endl;
}


MyComplex::~MyComplex()
{
}

运算符重载规则

并不是所有运算符都可以重载;

重载不能改变运算符的优先级和结合性;

重载不会改变运算符的用法(单目运算符仍然为单目运算符);

运算符重载不能有默认的参数;

运算符重载函数可以作为类的成员函数也可以作为全局函数(作为成员函数时使用参数个数应比目数少一,使用类中的this指针)。

箭头运算符 -> 下标运算符 [] 赋值运算符 = 函数调用运算符 () 只能以成员函数的形式重载。

重载 >> 和 <<

  1. 建议作为友元函数重载(避免使用this指针和修改内部库函数文件)
  2. 示例:
#include <iostream>
using namespace std;


class MyComplex
{
public:
	MyComplex(double real = 0.0, double imag = 0.0);

	friend istream & operator>>(istream & in, MyComplex & com);
	friend ostream & operator<<(ostream & out, const MyComplex & com);


private:
	double m_real;
	double m_imag;

};

istream & operator>>(istream & in, MyComplex & com)
{
	in >> com.m_real >> com.m_imag;
	return in;	// 返回值的作用是可以多次使用(istream & in)这个对象。
}

ostream & operator<<(ostream & out, const MyComplex & com)
{
	out << "(" << com.m_real << '+' << com.m_imag << 'i' << ')';
	return out;
}

int	main()
{
	MyComplex obj;
	MyComplex obj_1;

	cin >> obj >> obj_1;	// 等价于: operator>>(operator>>(cin, obj), obj_1);
	cout << obj << endl 
		<< obj_1 << endl;


	return 0;
}

/** MyComplex **/
MyComplex::MyComplex(double real, double imag)
	: m_real(real), m_imag(imag)
{
}

输出:

在这里插入图片描述

注意事项

  1. 运算符重载语法简单,关键是规则
  2. 可以显示调用(通过函数)也可以隐式调用(通过运算符)
  3. 注意与友元的联合使用(虽然会破坏封装,但是用起来很爽),可以考虑添加const 关键字,避免友元函数内修改私有数据成员。

<未完待续>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值