运算符重载:如何添加和比较两个 class "Integer" 和 "Fraction" 的数据

Operator Overloading: How to add and compare data of two class "Integer" and "Fraction"

我有两个 classes IntegerFraction 和一个摘要 class 人数。我想通过重载 + 来执行加法运算,我还需要在这些 classes.

上使用 == 运算符的重载来检查值的相等性

要执行的操作

1.添加整数 + 整数 = 整数

2。加分数 + 分数 = 分数

3。加整数 + 分数 = 分数

我可以进行第 1 次和第 2 次运算,但不能进行整数和分数的加法。

下面是代码片段:

  1. 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;
    
    };
    
  2. 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;
    
    };
    
  3. 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;
    }
    
  4. 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;
     };
    
  5. 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;
    }
    

问题:

  1. 我很困惑如何添加整数 + 分数 class。
  2. 我是否需要创建另一个 class,它将继承 Number class。
  3. 如何重载 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) 的任意组合。