前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++之运算符重载(一)

C++之运算符重载(一)

作者头像
zy010101
发布2020-04-08 16:41:44
4530
发布2020-04-08 16:41:44
举报
文章被收录于专栏:程序员

C++支持运算符重载。运算符重载的好处是使得使用类的人更加方便。设计类的人只不过是把设计函数变成了设计运算符重载。因此,运算符重载的本质仍旧是一个函数。

要想使用运算符重载,必须借助关键字operator。

C++对运算符重载是有限制的,其中: . :: ?: * sizeof 这五个运算符是不能被重载的。

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

运算符重载可以分为全局重载和成员函数重载;根据运算符的目数,可以分为单目运算符重载和双目运算符重载。

全局双目运算符重载

下面的代码将双目运算符重载为全局函数。

代码语言:javascript
复制
#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;
};
代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
#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的相加工作。此次的运算符重载使用了类提供的接口获取私有成员的值。更一般的做法是将全局运算符重载声明为类的友元函数。如下:

代码语言:javascript
复制
#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;
};

这样我们的运算符重载函数就可以访问类的私有成员了,可以改为如下:

代码语言:javascript
复制
MyComplex operator+(const MyComplex& c1, const MyComplex& c2)
{
	MyComplex tmp(c1.a + c2.a, c1.b + c2.b);
	return tmp;
}

这就是友元函数经常使用的地方。

成员函数双目运算符重载

代码语言:javascript
复制
#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);
};
代码语言:javascript
复制
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;
}
代码语言:javascript
复制
#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指针。所以我们只传递一个参数就够了。

全局重载单目运算符(前置++)

单目运算符只有一个操作数。他的重载比较复杂。首先在类内声明友元函数。注意必须传递引用才能实现单目得效果。

代码语言:javascript
复制
friend MyComplex& operator++(MyComplex& c);

然后实现如下:

代码语言:javascript
复制
MyComplex& operator++(MyComplex& c)
{
//要保证先自增,再被使用
	c.a++;
	c.b++;
	return c;
}

成员函数单目运算符重载(前置++)

代码语言:javascript
复制
MyComplex& MyComplex::operator++()
{
	this->a++;
	this->b++;
	return *this;
}

全局重载单目运算符(后置++)

后置++得函数原型和前置++不一样,否则编译器将认为这是一个函数的重定义。出于这一点考虑,C++要求后置运算符重载含有一个占位参数。这个参数什么用都没有,只是为了让编译器确定这是后置运算符。

代码语言:javascript
复制
friend MyComplex operator++(MyComplex& c, int);
代码语言:javascript
复制
MyComplex operator++(MyComplex& c, int)
{
//返回的是值,不是引用。
	MyComplex tmp(c);
	c.a++;
	c.b++;
	return tmp;
}

成员函数单目运算符重载(后置++)

代码语言:javascript
复制
MyComplex MyComplex::operator++(int)
{
	MyComplex tmp(*this);
	this->a++;
	this->b++;
	return tmp;
}

下面给出所有的代码:

代码语言:javascript
复制
//头文件
#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);
};
代码语言:javascript
复制
//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;
}
代码语言:javascript
复制
//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;
//}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 全局双目运算符重载
  • 成员函数双目运算符重载
  • 全局重载单目运算符(前置++)
  • 成员函数单目运算符重载(前置++)
  • 全局重载单目运算符(后置++)
  • 成员函数单目运算符重载(后置++)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档