C++ C++;使用类和函数的分数计算器

C++ C++;使用类和函数的分数计算器,c++,function,class,C++,Function,Class,我是新来的,从一所新学校开始。我希望能得到一些关于作业的指导。赋值是计算一个包含两个分数的表达式,并输出结果。我用课本上的知识编写这个程序已经好几天了,但我想我仍然对如何在一个类中实现函数感到困惑。我知道我想用我的价值观做什么,但我不知道应该把它们分配到哪里。我试图读入我的值,但当输出时,我得到了垃圾。任何帮助都将不胜感激 #include <iostream> using namespace std; class fraction

我是新来的,从一所新学校开始。我希望能得到一些关于作业的指导。赋值是计算一个包含两个分数的表达式,并输出结果。我用课本上的知识编写这个程序已经好几天了,但我想我仍然对如何在一个类中实现函数感到困惑。我知道我想用我的价值观做什么,但我不知道应该把它们分配到哪里。我试图读入我的值,但当输出时,我得到了垃圾。任何帮助都将不胜感激

  #include <iostream>
  using namespace std;
  class fraction                                        // Fraction class definition
  {
int num,
    den;
public:
fraction()                                      // default constructor
{
    num = 0;
    den = 1;
}
void add(fraction f1, fraction f2)                  // addition fcn
{
    num = (f1.num*f2.den) + (f2.num*f1.den);
    den = f1.den*f2.den;
}
void subtract(fraction f1, fraction f2)             // subtraction fcn
{
    num = (f1.num*f2.den) - (f2.num*f1.den);
    den = f1.den*f2.den;
}
void multiply(fraction f1, fraction f2)     // multiplying fcn
{
    num = f1.num*f2.num;
    den = f1.den*f2.den;
}
void divide(fraction f1, fraction f2)           // dividing fcn
{
    num = f1.num*f2.den;
    den = f1.den*f2.num;
}
void output()
{
    cout << num << "/" << den << endl;
}
};                                      // end Fraction class 


int main()
{                                   // begin main
    fraction result;
    fraction n;
    fraction d;
    int n1, n2, d1, d2 = 0;
    char op;
    cout << "Please enter an expression containing two fractions:" << endl;
    cin >> n1 >> d1 >> op >> n2 >> d2;

    switch (op) 
    {                                               // begin switch
    case '+':
        result.add(n, d);
        result.output();
        break;
    case '-':
        result.subtract(n, d);
        result.output();
        break;
    case '*':
        result.multiply(n, d);
        result.output();
        break;
    case'/':
        result.divide(n, d);
        result.output();
        break;
    }                                               // end switch

    //fraction f1(n1, d1);
    //fraction f2(n2, d2);



}                                   // end main
#包括
使用名称空间std;
类分数//分数类定义
{
int num,
兽穴
公众:
分数()//默认构造函数
{
num=0;
den=1;
}
空隙添加(分数f1,分数f2)//添加fcn
{
num=(f1.num*f2.den)+(f2.num*f1.den);
den=f1.den*f2.den;
}
空隙减法(分数f1,分数f2)//减法fcn
{
num=(f1.num*f2.den)-(f2.num*f1.den);
den=f1.den*f2.den;
}
空隙倍增(分数f1,分数f2)//倍增fcn
{
num=f1.num*f2.num;
den=f1.den*f2.den;
}
空隙分割(分数f1,分数f2)//分割fcn
{
num=f1.num*f2.den;
den=f1.den*f2.num;
}
无效输出()
{
cout op>>n2>>d2;
开关(op)
{//开始开关
格“+”:
结果:添加(n,d);
result.output();
打破
案例'-':
结果。减去(n,d);
result.output();
打破
案例“*”:
结果:乘以(n,d);
result.output();
打破
案例“/”:
结果:除以(n,d);
result.output();
打破
}//结束开关
//分数f1(n1,d1);
//分数f2(n2,d2);
}//末端总管

实际答案是在John3136的第一条评论中给出的。因此,我有点挣扎,但最终意识到您可能不认识。因此,我将对此进行详细说明:

main()
中,可以执行以下操作:

int n1, n2, d1, d2 = 0;
char op;
cout << "Please enter an expression containing two fractions:" << endl;
cin >> n1 >> d1 >> op >> n2 >> d2;
变量将显示以下值:

n1: 1
d1: 2
n2: 3
d2: 4
op: '+'
现场演示

进一步,程序指针将移动到

result.add(n, d);
嗯。你想添加
n
d
,但调试器说:

n: { num: 0, den: 1 }
d: { num: 0, den: 1 }
n.num
n.den
d.num
d.den
的值都在这里,因为您为
类分数
提供了一个默认构造函数,它正好实现了这一点

那么,您认为
n1
将如何移动到
n.num
d1
n.den
,等等

真正缺少的是
类分数
的构造函数,它用指定的值加载成员
num
den
(在这种情况下是
n
d

您可以引入第二个构造函数。在这种情况下,您可以修改(和扩展)现有构造函数,还可以:

class fraction {

  private:
    int num, den; // numerator, denominator

  public:

    explicit fraction(int num = 0, int den = 1): num(num), den(den) { }

};
看起来很困惑?我会解释:

  • 我给出了构造函数参数,但参数得到了默认值。 因此,它仍然可以用作默认构造函数。执行
    分数a;
    将像以前一样构造分数0/1。但是,现在,您也可以执行
    分数b(3,2);
    来构造分数3/2。您甚至可以执行
    分数d(3);
    。这将构造分数3/1,听起来很合理

  • 我将参数命名为等于成员。看起来很有趣,可能有点混乱,但现在似乎很常见。(事实上,我在这么短的时间前就学会了这一点。)然而,编译器将正确理解这一点(即使它是MS的一个)

  • 我在构造函数前面加了
    explicit
    。这防止了构造函数可能被用于隐式转换。如果没有
    explicit
    ,以下操作也会起作用:
    分数c;c=1;
    ,即从
    int
    分配
    类分数。这是一个设计问题您希望支持此功能。隐式转换非常方便,但编译器可能会在您不希望的地方应用它。我个人习惯于使几乎每个构造函数
    显式
    ,因为我不喜欢“失控”编译器正在执行的操作

  • 按照建议修改上述构造函数,然后可以使用您的类,例如:

    fraction a(3, 2), b(1, 2);
    fraction result; result.add(a, b);
    result.output();
    
    现在,它应该打印分数
    a
    b
    的总和

    最后一点:

    我认为O'NeIL的提示与运算符重载基本上是合理的。你会在代码中找到答案。(其中有些是我写的);另一方面,运算符重载只是另一个障碍。我不会太担心这个问题。(可能是,在第二个版本中)

    最后,我用示例代码演示了上述内容:

    #include <iostream>
    using namespace std;
    
    class fraction {
    
      private:
        int num, den; // numerator, denominator
    
      public:
    
        explicit fraction(int num = 0, int den = 1): num(num), den(den) { }
    
        void add(fraction f1, fraction f2) // addition fcn
        {
          num = (f1.num * f2.den) + (f2.num * f1.den);
          den = f1.den * f2.den;
        }
    
        void output() { cout << num << "/" << den << endl; }
    };
    
    int main()
    {
      fraction a0;
      cout << "fraction a0: "; a0.output();
      fraction a(3, 2), b(1);
      cout << "fraction a(3, 2): "; a.output();
      cout << "fraction b(1): "; b.output();
      fraction c; c.add(a, b);
      cout << "fraction c = a + b: "; c.output();
      // assignment (using default assignment operator)
      fraction d; d = c;
      cout << "faction d = c; d: "; d.output();
    #if 0 // disabled code
      // This will work only if constructor is not explicit:
      fraction e = 1; e = 1;
      cout << "fraction e; e = 1; e: "; e.output();
    #endif // 0
      // fraction from input
      int n1, n2;
      cout << "Input n1 n2: "; cin >> n1 >> n2;
      fraction in(n1, n2);
      cout << "fraction in(n1, n2): "; in.output();
      // done
      return 0;
    }
    
    输出:

    分数a0:0/1
    分数a(3,2):3/2
    分数b(1):1/1
    分数c=a+b:5/2
    势力d=c;势力d:5/2
    输入n1 n2:n1,n2中的分数:123/321
    
    现场演示


    在阅读了您的评论之后,我怀疑您是否已经理解了
    和成员函数的概念。我将尽最大努力:

    您是否知道您的函数
    add()
    是一个成员函数?正如您在
    类分数中定义的那样。这意味着,如果没有对象(即
    分数的实例
    ),就无法调用
    add()

    如果将其写入
    main()
    函数,则会出现编译器错误:

    fraction a, b;
    fraction::add(a, b);
    
    现场演示

    对象是(非
    静态
    )成员函数(如
    分数::add()
    )的调用迫切需要的另一个参数。可能是,您没有识别
    fraction a, b;
    fraction::add(a, b);
    
    fraction c; c.add(a, b);
    /*          ^     ^  ^
     *          |     |  +--- 2nd argument
     *          |     +------ 1st argument
     *          +------------ object (which becomes THE this POINTER inside fraction::add())
     */
    
    result.add(n, d);