运算符重载:如何添加和比较两个 class "Integer" 和 "Fraction" 的数据
Operator Overloading: How to add and compare data of two class "Integer" and "Fraction"
我有两个 classes Integer 和 Fraction 和一个摘要 class 人数。我想通过重载 +
来执行加法运算,我还需要在这些 classes.
上使用 ==
运算符的重载来检查值的相等性
要执行的操作
1.添加整数 + 整数 = 整数
2。加分数 + 分数 = 分数
3。加整数 + 分数 = 分数
我可以进行第 1 次和第 2 次运算,但不能进行整数和分数的加法。
下面是代码片段:
Number.h
#pragma once
#include <iostream>
template<class T>
class Number
{
virtual const T operator+ (const T &) = 0;
virtual void display(std::ostream &) const = 0;
virtual bool operator==(const T& rhs) const = 0;
};
Integer.h
#pragma once
#include "Number.h"
#include "Fraction.h"
class Integer : public Number<Integer>
{
int intValue;
public:
void display(std::ostream &) const;
int getValue() const;
void setValue(int);
Integer() {}
Integer(int num);
const Integer operator+ (const Integer &);
virtual ~Integer() {}
bool operator==(const Integer&) const;
};
Integer.cpp
#include "Integer.h"
#include "Number.h"
#include <iostream>
#include <string>
// parameterized constructor
Integer::Integer(int num)
{
intValue = num;
}
// return integer value
int Integer::getValue() const
{
return this->intValue;
}
void Integer::setValue(int x)
{
this->intValue = x;
}
// operator "+" overloading
const Integer Integer::operator+(const Integer &secondNumber)
{
Integer temp = this->intValue + secondNumber.intValue;
return temp;
}
// operator "=" overloading
void Integer::display(std::ostream& stream) const
{
stream << this->intValue;
}
// comparasion operator overload
bool Integer::operator==(const Integer& rhs) const
{
return this->intValue == rhs.intValue;
}
Fraction.h
#pragma once
#include "Number.h"
#include "Integer.h"
class Fraction : public Number<Fraction>
{
Integer _numerator;
Integer _denominator;
public:
void display(std::ostream &) const;
Fraction() = delete;
Fraction(const int &, const int &);
const Fraction operator+ (const Fraction &);
int gcdCalculate(int val1, int val2);
int lcmCalculate(const int val1, const int val2);
virtual ~Fraction() {}
bool operator==(const Fraction& rhs) const;
};
Fraction.cpp
#include "Fraction.h"
#include <iostream>
// parameterised constructor
Fraction::Fraction(const int & num, const int & den)
{
_numerator.setValue(num);
_denominator.setValue(den);
}
// display the fraction value
void Fraction::display(std::ostream & stream) const
{
if (this->_denominator == 0)
std::cout << "Undefined: " << this->_numerator.getValue() << "/" << this->_denominator.getValue() << " (Divide By Zero Exception)";
else
stream << this->_numerator.getValue() << "/" << this->_denominator.getValue();
}
// "+" operator overloading
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
int lcm = lcmCalculate(this->_denominator.getValue(), numberTwo._denominator.getValue());
int multiplier1 = 0;
if (this->_denominator.getValue())
multiplier1 = lcm / this->_denominator.getValue();
int multiplier2 = 0;
if (numberTwo._denominator.getValue())
multiplier2 = lcm / numberTwo._denominator.getValue();
return Fraction((this->_numerator.getValue() * multiplier1) + (numberTwo._numerator.getValue() * multiplier2), lcm);
}
// LCM Calculation
int Fraction::lcmCalculate(const int val1, const int val2)
{
int temp = gcdCalculate(val1, val2);
return temp ? (val1 / temp * val2) : 0;
}
// GCD Calculation
int Fraction::gcdCalculate(int val1, int val2)
{
for (;;)
{
if (val1 == 0) return val2;
val2 %= val1;
if (val2 == 0) return val1;
val1 %= val2;
}
}
// comparision operator overload
bool Fraction::operator==(const Fraction& rhs) const
{
Integer numCheck = this->_numerator;
Integer denCheck = this->_denominator;
if (rhs._numerator.getValue())
numCheck.setValue(numCheck.getValue() / rhs._numerator.getValue());
if (rhs._numerator.getValue())
denCheck.setValue(denCheck.getValue() / rhs._denominator.getValue());
if (numCheck == denCheck) {
return true;
}
return false;
}
问题:
- 我很困惑如何添加整数 + 分数 class。
- 我是否需要创建另一个 class,它将继承 Number class。
- 如何重载
Number Class
中的 oprator+
。
假设我尝试在 Integer class 本身中添加 Integer + Fraction = Fraction
然后我会得到类似的东西
例子
class Integer : public Number<Integer>
{
const Fraction operator+(const Fraction &);
}
const Fraction Integer::operator+(const Fraction &numberTwo)
{
^^ I will get error here
// Addition opeartion
}
请帮帮我。
对于你的第一个问题,解决方案是不使用成员函数重载,而是创建一个非成员函数重载,例如
Fraction operator+(Integer const& integer, Fraction const& fraction)
{
// Logic to add the integer and fraction here
// Perhaps something like...
Fraction f(integer.getValue(), 1); // Create fraction
return f + fraction;
}
上面的代码使用 Fraction::operator+
函数来添加整数。
虽然您可以像 Joachim 建议的那样将 Integer
+Fraction
运算符添加到您当前的设计中,但这将导致一些代码重复或至少一些不必要的样板文件。
我建议另一种设计:将 Integer
convertible 改为 Fraction
。毕竟,任何整数都可以用 Fraction
类型表示,对吧?
您可以通过两种方式使 Integer
可转换:将 conversion function to Integer
, or by adding a converting constructor 添加到 Fraction
。
我建议选择转换构造函数方法,因为 Fraction
已经依赖于 Integer
类型,因此强制转换运算符会导致循环依赖,就像您的成员运算符尝试一样。我将把实施留作练习。
此设计要求将加法运算符实现为非成员重载:
Fraction operator+(Fraction const& left, Fraction const& right)
使用转换构造函数,此函数可以处理 (F + F)、(F + I) 和 (I + F) 的任意组合。
我有两个 classes Integer 和 Fraction 和一个摘要 class 人数。我想通过重载 +
来执行加法运算,我还需要在这些 classes.
==
运算符的重载来检查值的相等性
要执行的操作
1.添加整数 + 整数 = 整数
2。加分数 + 分数 = 分数
3。加整数 + 分数 = 分数
我可以进行第 1 次和第 2 次运算,但不能进行整数和分数的加法。
下面是代码片段:
Number.h
#pragma once #include <iostream> template<class T> class Number { virtual const T operator+ (const T &) = 0; virtual void display(std::ostream &) const = 0; virtual bool operator==(const T& rhs) const = 0; };
Integer.h
#pragma once #include "Number.h" #include "Fraction.h" class Integer : public Number<Integer> { int intValue; public: void display(std::ostream &) const; int getValue() const; void setValue(int); Integer() {} Integer(int num); const Integer operator+ (const Integer &); virtual ~Integer() {} bool operator==(const Integer&) const; };
Integer.cpp
#include "Integer.h" #include "Number.h" #include <iostream> #include <string> // parameterized constructor Integer::Integer(int num) { intValue = num; } // return integer value int Integer::getValue() const { return this->intValue; } void Integer::setValue(int x) { this->intValue = x; } // operator "+" overloading const Integer Integer::operator+(const Integer &secondNumber) { Integer temp = this->intValue + secondNumber.intValue; return temp; } // operator "=" overloading void Integer::display(std::ostream& stream) const { stream << this->intValue; } // comparasion operator overload bool Integer::operator==(const Integer& rhs) const { return this->intValue == rhs.intValue; }
Fraction.h
#pragma once #include "Number.h" #include "Integer.h" class Fraction : public Number<Fraction> { Integer _numerator; Integer _denominator; public: void display(std::ostream &) const; Fraction() = delete; Fraction(const int &, const int &); const Fraction operator+ (const Fraction &); int gcdCalculate(int val1, int val2); int lcmCalculate(const int val1, const int val2); virtual ~Fraction() {} bool operator==(const Fraction& rhs) const; };
Fraction.cpp
#include "Fraction.h" #include <iostream> // parameterised constructor Fraction::Fraction(const int & num, const int & den) { _numerator.setValue(num); _denominator.setValue(den); } // display the fraction value void Fraction::display(std::ostream & stream) const { if (this->_denominator == 0) std::cout << "Undefined: " << this->_numerator.getValue() << "/" << this->_denominator.getValue() << " (Divide By Zero Exception)"; else stream << this->_numerator.getValue() << "/" << this->_denominator.getValue(); } // "+" operator overloading const Fraction Fraction::operator+(const Fraction &numberTwo) { int lcm = lcmCalculate(this->_denominator.getValue(), numberTwo._denominator.getValue()); int multiplier1 = 0; if (this->_denominator.getValue()) multiplier1 = lcm / this->_denominator.getValue(); int multiplier2 = 0; if (numberTwo._denominator.getValue()) multiplier2 = lcm / numberTwo._denominator.getValue(); return Fraction((this->_numerator.getValue() * multiplier1) + (numberTwo._numerator.getValue() * multiplier2), lcm); } // LCM Calculation int Fraction::lcmCalculate(const int val1, const int val2) { int temp = gcdCalculate(val1, val2); return temp ? (val1 / temp * val2) : 0; } // GCD Calculation int Fraction::gcdCalculate(int val1, int val2) { for (;;) { if (val1 == 0) return val2; val2 %= val1; if (val2 == 0) return val1; val1 %= val2; } } // comparision operator overload bool Fraction::operator==(const Fraction& rhs) const { Integer numCheck = this->_numerator; Integer denCheck = this->_denominator; if (rhs._numerator.getValue()) numCheck.setValue(numCheck.getValue() / rhs._numerator.getValue()); if (rhs._numerator.getValue()) denCheck.setValue(denCheck.getValue() / rhs._denominator.getValue()); if (numCheck == denCheck) { return true; } return false; }
问题:
- 我很困惑如何添加整数 + 分数 class。
- 我是否需要创建另一个 class,它将继承 Number class。
- 如何重载
Number Class
中的oprator+
。
假设我尝试在 Integer class 本身中添加 Integer + Fraction = Fraction
然后我会得到类似的东西
例子
class Integer : public Number<Integer>
{
const Fraction operator+(const Fraction &);
}
const Fraction Integer::operator+(const Fraction &numberTwo)
{
^^ I will get error here
// Addition opeartion
}
请帮帮我。
对于你的第一个问题,解决方案是不使用成员函数重载,而是创建一个非成员函数重载,例如
Fraction operator+(Integer const& integer, Fraction const& fraction)
{
// Logic to add the integer and fraction here
// Perhaps something like...
Fraction f(integer.getValue(), 1); // Create fraction
return f + fraction;
}
上面的代码使用 Fraction::operator+
函数来添加整数。
虽然您可以像 Joachim 建议的那样将 Integer
+Fraction
运算符添加到您当前的设计中,但这将导致一些代码重复或至少一些不必要的样板文件。
我建议另一种设计:将 Integer
convertible 改为 Fraction
。毕竟,任何整数都可以用 Fraction
类型表示,对吧?
您可以通过两种方式使 Integer
可转换:将 conversion function to Integer
, or by adding a converting constructor 添加到 Fraction
。
我建议选择转换构造函数方法,因为 Fraction
已经依赖于 Integer
类型,因此强制转换运算符会导致循环依赖,就像您的成员运算符尝试一样。我将把实施留作练习。
此设计要求将加法运算符实现为非成员重载:
Fraction operator+(Fraction const& left, Fraction const& right)
使用转换构造函数,此函数可以处理 (F + F)、(F + I) 和 (I + F) 的任意组合。