当前位置: 首页 > news >正文

C++进阶:使用普通函数重载算数运算符

一般来说,如果可以利用现有的成员函数(接触类内部的函数越少越好),则应优先使用普通函数而不是友元函数。但是,不要仅仅为了将运算符重载为普通函数而不是友元函数而添加额外的访问函数

单文件 main.cpp

  1 #include <numeric>  // for std::gdb2 #include <iostream>34 class Fraction5 {6 private:7     int m_numerator {};8     int m_denominator { };910 public:11     explicit Fraction(int numerator, int denominator = 1)12         : m_numerator{ numerator }, m_denominator{ denominator }13     { }1415 	16     int getNumerator() const17     {18         return m_numerator;19     }2021     int getDenominator() const22     {23         return m_denominator;24     }2526     void reduce();27     void print();28 };2930 Fraction operator*(const Fraction& f1, const Fraction& f2);31 Fraction operator*(const Fraction& f1, int value);32 Fraction operator*(int value, const Fraction& f1);3334 Fraction operator*(const Fraction& f1, const Fraction& f2)35 {36     return Fraction{ f1.getNumerator() * f2.getNumerator(), f1.getDenominator() * f2.getDenominator() };37 }383940 Fraction operator*(const Fraction& f1, int value)41 {42     return Fraction{ f1.getNumerator() * value, f1.getDenominator() };43 }4445 Fraction operator*(int value, const Fraction& f1)46 {47     return Fraction{ f1.getNumerator() * value, f1.getDenominator() };48 }4950 void Fraction::reduce()51 {52     int m_gcd{ std::gcd(m_numerator, m_denominator) };53     if (m_gcd) // Make sure we don't try to divide by 054     {55         m_numerator /= m_gcd;56         m_denominator /= m_gcd;57     }58 }59 void Fraction::print()60 {61     Fraction::reduce();62     std::cout << m_numerator<< "/" << m_denominator << '\n';63 }6465 int main()66 {67     Fraction f1{ 1, 4};68     f1.print();6970     Fraction f2{ 1, 2 };71     f2.print();7273     Fraction f3{ f1 * f2 };74     f3.print();7576     Fraction f4{ 2 * f1 };77     f4.print();7879     Fraction f5{ f1 * 3 };80     f5.print();8182     Fraction f6{ Fraction{1, 2} * Fraction{2, 3} * Fraction{3, 4} };83     f6.print();8485     return 0;86 }87

改写多文件
将类和声明放到头文件里面,为防止单个文件重复使用声明,加上条件编译保护机制。
具体操作:将上面4~32行放到Fraction.h文件加上标识符为FRACTION_H的头文件保护机制
Fraction.h

#ifndef FRACTION_H
#define FRACTION_H
class Fraction
{
private:int m_numerator {};int m_denominator { };public:explicit Fraction(int numerator, int denominator = 1): m_numerator{ numerator }, m_denominator{ denominator }{ }int getNumerator() const{return m_numerator;}int getDenominator() const{return m_denominator;}void reduce();void print();
};Fraction operator*(const Fraction& f1, const Fraction& f2);
Fraction operator*(const Fraction& f1, int value);
Fraction operator*(int value, const Fraction& f1);
#endif

将头文件Fraction.h的具体实现放入到Fration.cpp中,最好包含Fraction.h,表示结构上关系的清晰(不引入自会编译器自会寻找),再包含进所用到的头文件。
具体操作:将34~64行放入Fration.cpp中,因为求两数最大公约数的std::gcd是文件中的,也用到了std::cout,所以和也#include 进去。
Fration.cpp

#include "Fraction.h"
#include <numeric>
#include <iostream>
Fraction operator*(const Fraction& f1, const Fraction& f2)
{return Fraction{ f1.getNumerator() * f2.getNumerator(), f1.getDenominator() * f2.getDenominator() };
}Fraction operator*(const Fraction& f1, int value)
{return Fraction{ f1.getNumerator() * value, f1.getDenominator() };
}Fraction operator*(int value, const Fraction& f1)
{return Fraction{ f1.getNumerator() * value, f1.getDenominator() };
}
void Fraction::reduce()
{int m_gcd{ std::gcd(m_numerator, m_denominator) };if (m_gcd) // Make sure we don't try to divide by 0{m_numerator /= m_gcd;m_denominator /= m_gcd;}
}
void Fraction::print()
{Fraction::reduce();std::cout << m_numerator<< "/" << m_denominator << '\n';
}                      

剩下的就是main.cpp 了,将Fraction.h包含进来,删掉没用到的头文件就可以了。
main.cpp

#include "Fraction.h"int main()
{Fraction f1{ 1, 4};f1.print();Fraction f2{ 1, 2 };f2.print();Fraction f3{ f1 * f2 };f3.print();Fraction f4{ 2 * f1 };f4.print();Fraction f5{ f1 * 3 };f5.print();Fraction f6{ Fraction{1, 2} * Fraction{2, 3} * Fraction{3, 4} };f6.print();return 0;
}

确保这个三个文件都在同一目录下面,然后就开始编译了。

在这里插入图片描述
单独编译各个文件都没有编译方面的问题。
在这里插入图片描述
使用lld链接也没有问题,运行可执行文件a.out按照预期输入了化简后的分数。
在这里插入图片描述

http://www.dtcms.com/a/452811.html

相关文章:

  • 从内核调优到集群部署:基于Linux环境下KingbaseES数据库安装指南
  • Micro850 控制器深度解析:硬件特性与 I/O 接线核心(罗克韦尔2)
  • Python oct() 函数
  • (一) 机器学习之深度神经网络
  • C语言指针全面解析:从内存管理到高级应用
  • 南通网站建设推广专家建站教程的优点
  • Spring Boot整合Apache Shiro权限认证框架(应用篇)
  • 杰理AC632N---RTC应用问题
  • 网站免费软件下载阳江人社局官网招聘
  • 第二十三章:解析天书,诠释法则——Interpreter的解释艺术
  • 论文阅读-FoundationStereo
  • bug日记
  • 大数据集群环境搭建(Ubantu)
  • 深入浅出 HarmonyOS 应用开发:ArkTS 语法精要与实践
  • 用 Python+OpenCV 实现实时文档扫描:从摄像头捕捉到透视矫正全流程
  • 普陀做网站公司任丘市建设局网站
  • 前端框架篇——VueReact篇
  • R语言从入门到精通Day4之【数据结构】
  • JavaScript快速入门_javascript入门教程
  • 有几家做网站的公司易贝跨境电商平台
  • 基于websocket的多用户网页五子棋(六)
  • 月光与饼:Python 爱情月饼可视化
  • 【C++】STL有序关联容器的双生花:set/multiset 和 map/multimap 使用指南
  • 迷你论坛项目
  • 【C++STL】一文掌握 String 核心接口:从基础到实用!
  • 长沙宁乡建设网站网站本地环境搭建
  • 从以太网到多个 CAN 网络的网关
  • 网站做弹窗怀化职院网站
  • ros2 功能包 package.xml 结构详细解释
  • ros2 功能包 CMakeLists.txt 结构详细解释