0.目录

1.操作符重载

2.完善的复数类

3.小结

1.操作符重载

下面的复数解决方案是否可行?

示例1——原有的解决方案:

#include <stdio.h>

class Complex
{
int a;
int b;
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
} int getA() { return a; } int getB() { return b; } friend Complex Add(const Complex& p1, const Complex& p2);
}; Complex Add(const Complex& p1, const Complex& p2)
{
Complex ret; ret.a = p1.a + p2.a;
ret.b = p1.b + p2.b; return ret;
} int main()
{
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3 = Add(c1, c2); // c1 + c2 printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
c3.a = 4, c3.b = 6

操作符重载:

  • C++中的重载能够扩展操作符的功能
  • 操作符的重载以函数的方式进行
  • 本质——用特殊形式的函数扩展操作符的功能

通过operator关键字可以定义特殊的函数

operator的本质是通过函数重载操作符

语法:

示例2——使用操作符重载函数代替原有函数:

#include <stdio.h>

class Complex
{
int a;
int b;
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
} int getA() { return a; } int getB() { return b; } friend Complex operator + (const Complex& p1, const Complex& p2);
}; Complex operator + (const Complex& p1, const Complex& p2)
{
Complex ret; ret.a = p1.a + p2.a;
ret.b = p1.b + p2.b; return ret;
} int main()
{
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3 = operator + (c1, c2); // c1 + c2 printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
c3.a = 4, c3.b = 6

可以将操作符重载函数定义为类的成员函数:

  • 比全局操作符重载函数少一个参数(左操作符)
  • 不需要依赖友元就可以完成操作符重载
  • 编译器优先在成员函数中寻找操作符重载函数

示例3——不使用友元,而是使用类的成员函数(编译器优先在成员函数中寻找操作符重载函数):

#include <stdio.h>

class Complex
{
int a;
int b;
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
} int getA() { return a; } int getB() { return b; } Complex operator + (const Complex& p)
{
Complex ret;
printf("Complex operator + (const Complex& p)\n");
ret.a = this->a + p.a;
ret.b = this->b + p.b; return ret;
} friend Complex operator + (const Complex& p1, const Complex& p2);
}; Complex operator + (const Complex& p1, const Complex& p2)
{
Complex ret;
printf("Complex operator + (const Complex& p1, const Complex& p2)\n");
ret.a = p1.a + p2.a;
ret.b = p1.b + p2.b; return ret;
} int main()
{
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3 = c1 + c2; // c1.operator + (c2) printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Complex operator + (const Complex& p)
c3.a = 4, c3.b = 6

2.完善的复数类

复数类应该具有的操作:

利用操作符重载:

  • 统一复数与实数的运算方式
  • 统一复数与实数的比较方式

先实现Complex.h头文件:

// Complex.h
#ifndef _COMPLEX_H_
#define _COMPLEX_H_ class Complex
{
double a;
double b;
public:
Complex(double a = 0, double b = 0);
double getA();
double getB();
double getModulus(); Complex operator + (const Complex& c);
Complex operator - (const Complex& c);
Complex operator * (const Complex& c);
Complex operator / (const Complex& c); bool operator == (const Complex& c);
bool operator != (const Complex& c); Complex& operator = (const Complex& c);
}; #endif

再实现Complex.cpp具体操作:

// Complex.cpp
#include "Complex.h"
#include "math.h" Complex::Complex(double a, double b)
{
this->a = a;
this->b = b;
} double Complex::getA()
{
return a;
} double Complex::getB()
{
return b;
} double Complex::getModulus()
{
return sqrt(a * a + b * b);
} Complex Complex::operator + (const Complex& c)
{
double na = a + c.a;
double nb = b + c.b;
Complex ret(na, nb); return ret;
} Complex Complex::operator - (const Complex& c)
{
double na = a - c.a;
double nb = b - c.b;
Complex ret(na, nb); return ret;
} Complex Complex::operator * (const Complex& c)
{
double na = a * c.a - b * c.b;
double nb = a * c.b + b * c.a;
Complex ret(na, nb); return ret;
} Complex Complex::operator / (const Complex& c)
{
double cm = c.a * c.a + c.b * c.b;
double na = (a * c.a + b * c.b) / cm;
double nb = (b * c.a - a * c.b) / cm;
Complex ret(na, nb); return ret;
} bool Complex::operator == (const Complex& c)
{
return (a == c.a) && (b == c.b);
} bool Complex::operator != (const Complex& c)
{
return !(*this == c);
} Complex& Complex::operator = (const Complex& c)
{
if( this != &c )
{
a = c.a;
b = c.b;
} return *this;
}

最后实现main函数:

// test.cpp
#include <stdio.h>
#include "Complex.h" int main()
{
Complex c1(1, 2);
Complex c2(3, 6);
Complex c3 = c2 - c1;
Complex c4 = c1 * c3;
Complex c5 = c2 / c1; printf("c3.a = %f, c3.b = %f\n", c3.getA(), c3.getB());
printf("c4.a = %f, c4.b = %f\n", c4.getA(), c4.getB());
printf("c5.a = %f, c5.b = %f\n", c5.getA(), c5.getB()); Complex c6(2, 4); printf("c3 == c6 : %d\n", c3 == c6);
printf("c3 != c4 : %d\n", c3 != c4); (c3 = c2) = c1; printf("c1.a = %f, c1.b = %f\n", c1.getA(), c1.getB());
printf("c2.a = %f, c2.b = %f\n", c2.getA(), c2.getB());
printf("c3.a = %f, c3.b = %f\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp Complex.cpp
[root@bogon Desktop]# ./a.out
c3.a = 2.000000, c3.b = 4.000000
c4.a = -6.000000, c4.b = 8.000000
c5.a = 3.000000, c5.b = 0.000000
c3 == c6 : 1
c3 != c4 : 1
c1.a = 1.000000, c1.b = 2.000000
c2.a = 3.000000, c2.b = 6.000000
c3.a = 1.000000, c3.b = 2.000000

注意事项:

  • C++规定赋值操作符(=)只能重载为成员函数
  • 操作符重载不能改变原操作符的优先级
  • 操作符重载不能改变操作符的个数
  • 操作符重载不应改变操作符的原有语义

3.小结

  • 操作符重载是C++的强大特性之一
  • 操作符重载的本质是通过函数扩展操作符的功能
  • operator关键字是实现操作符重载的关键
  • 操作符重载遵循相同的函数重载规则
  • 全局函数和成员函数都可以实现对操作符的重载
  • 复数的概念可以通过自定义类实现
  • 复数中的运算操作可以通过操作符重载实现
  • 赋值操作符只能通过成员函数实现
  • 操作符重载的本质为函数定义

C++解析(17):操作符重载的更多相关文章

  1. Kotlin操作符重载:把标准操作加入到任何类中(KAD 17)

    作者:Antonio Leiva 时间:Mar 21, 2017 原文链接:https://antonioleiva.com/operator-overload-kotlin/ 就像其他每种语言一样, ...

  2. 析构函数-复制构造函数-赋值操作符重载-默认构造函数<代码解析>

    通过下面primer中的一道习题,可以更深刻的了解,析构函数,复制构造函数,赋值操作符重载,默认构造函数的使用. 但是我的结果与primer习题解答里面的并不相同,可能是编译器不同的原因导致. // ...

  3. lua 14 metatable (类似操作符重载)

    转自:http://www.runoob.com/lua/lua-metatables.html 感性认识: “Lua中Metatable这个概念, 国内将他翻译为元表. 元表为重定义Lua中任意一个 ...

  4. 【转】Python3 操作符重载方法

    Python3 操作符重载方法 本文由 Luzhuo 编写,转发请保留该信息. 原文: http://blog.csdn.net/Rozol/article/details/70769628 以下代码 ...

  5. 5.1 C++基本操作符重载

    参考:http://www.weixueyuan.net/view/6379.html 总结: 操作符重载指的是将C++提供的操作符进行重新定义,使之满足我们所需要的一些功能. 长度运算符“sizeo ...

  6. 侯捷STL学习(四)--OOP-GP/操作符重载-泛化特化

    C++标准库第二讲 体系结构与内核分析 第1-7节为第一讲 读源代码前的准备 第八节:源代码分布 C++基本语法 模板的使用 数据结构和算法 本课程主要使用:Gnu C 2.9.1与Gun C 4.9 ...

  7. C++ 操作符重载 (operator)

    重载不能改变操作符的优先级 如果一个内建操作符是一元的,那么所有对它的重载仍是一元的.如果是二元的重载后也是二元的 下面看一个有代表性的例子:: 头文件Complex.h: #includeusing ...

  8. c++ 操作符重载和友元

    操作符重载(operator overloading)是C++中的一种多态,C++允许用户自定义函数名称相同但参数列表不同的函数,这被称为函数重载或函数多态.操作符重载函数的格式一般为: operat ...

  9. paip.操作符重载的缺失 Java 的一个大缺点

    paip.操作符重载的缺失 Java 的一个大缺点 #----操作符重载的作用 1.提升用户体验 操作符重载..可以让代码更加自然.... 2.轻松实现代码代码移植 例如   java代码会直接移植到 ...

随机推荐

  1. 系统分析与设计——WordCount

    成果: https://gitee.com/ZMLJZ/codes/0k19q4upgmrfde265l7vx36 作业要求: 根据WordCount的需求描述,先编程实现,再编写单元测试,最后撰写博 ...

  2. 【LG5022】[NOIP2018]旅行

    [LG5022][NOIP2018]旅行 题面 洛谷 题解 首先考虑一棵树的部分分怎么打 直接从根节点开始\(dfs\),依次选择编号最小的儿子即可 而此题是一个基环树 怎么办呢? 可以断掉环上的一条 ...

  3. CF 1083 C. Max Mex

    C. Max Mex https://codeforces.com/contest/1083/problem/C 题意: 一棵$n$个点的树,每个点上有一个数(每个点的上的数互不相同,而且构成一个0~ ...

  4. 搜索引擎ElasticSearch系列(五): ElasticSearch2.4.4 IK中文分词器插件安装

    一:IK分词器简介  IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本.最初,它是以开源 ...

  5. 解决E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable) E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

    是不是在使用ubuntu的时候特别是安装或更新的时候会出现下面的情况:  E: Could not get lock /var/lib/dpkg/lock - open (11: Resource t ...

  6. Selenium2+python自动化-环境搭建

    一.selenium简介 Selenium 是用于测试 Web 应用程序用户界面 (UI) 的常用框架.它是一款用于运行端到端功能测试的超强工具.您可以使用多个编程语言编写测试,并且 Selenium ...

  7. 高可用Kubernetes集群-4. kubectl客户端工具

    六.部署kubectl客户端工具 1. 下载 [root@kubenode1 ~]# cd /usr/local/src/ [root@kubenode1 src]# wget https://sto ...

  8. 性能度量RMSE

    回归问题的典型性能度量是均方根误差(RMSE:Root Mean Square Error).如下公式. m为是你计算RMSE的数据集中instance的数量. x(i)是第i个实例的特征值向量 ,y ...

  9. New Year_2019

    新年目标 1. own的项目稳定高效,业务能满足业务方需求,功能质量超出业务方期待.2. 工作中成长,包括项目的需求管理,计划排期,整体的把控能力.3. 对公司的业务了解程度达到更高程度. 个人技能目 ...

  10. 项目进行ing

    1.我们的看板 2.立行会议 (1)照片 (2)时间:每天20:00 (3)地点:学校研发中心会议室 3.看板进展: 已有6个任务被移到Check Out栏中,详细情况如下: 梁植淋:构建项目架构,封 ...