繁体   English   中英

重载>>用于分数类C ++

[英]overloading >> for a fraction class C++

我正在尝试为一个分数类重载instream运算符>>。 我创建了一个函数,可以从用户获取一个字符串并将其解析为我的Fraction类的正确参数,但我不确定如何在我的>>重载函数中实现它。

用户可以输入三种类型的分数:1。整数(例如5)2。混合数(例如2 + 4/5)3。常规分数(例如1/2)

我的方法是将此输入作为主函数中用户的字符串接受,解析它以获取有效的Fraction类参数,然后将此新创建的fraction对象返回到流。 我只是不确定如何做到这一点。

在我的运算符重载定义中,我有这个:

istream& operator>>(istream& in,const Fraction& input)

但是如果我接受一个字符串,那么这里的参数类型不应该是一个字符串吗? 我对这一部分感到非常困惑。 我想再返回一个Fraction对象。 这是处理整数的一个例子。

    int num1 = atoi(input.c_str());
    Fraction output(num1);
    in >> output;
    return in;

我在这里走在正确的轨道上吗?

您的分数需要是输出参数,因此它不能是const

istream& operator>>(istream& in, Fraction& input)

然后在函数内部,您将提取到一个std::string ,然后将其解析,并将相关数据存储到input Fraction对象中。

这是我为演示代码所做的事情,因为其他人已经解释了这些问题。

class Fraction {
int top, bottom;
public:
    Fraction(int top_, int bottom_) :top(top_), bottom(bottom_) {}
    Fraction(const Fraction& rhs) : top(rhs.top), bottom(rhs.bottom) {}
    Fraction& operator=(const Fraction& rhs) {top=rhs.top; bottom=rhs.bottom; return *this}

    int get_numerator() {return top;}
    int get_denomerator() {return bottom;}
    double get_value() {return double(top)/bottom;}
};

istream& operator>>(istream& in, Fraction& input) {
    int numer;
    int denom=1;
    int whole=0;
    int peekchar;
    bool valid=false;

    in >> numer; //get the numerator
    peekchar = in.peek(); //peek at next character
    if(in && peekchar == '+') { //if next character is a +
        in.get(); //skip the + character
        whole = numer; //then first character was whole, not numerator
        in >> numer; //get the real numerator
        valid = true;
        peekchar = in.peek();
    }
    if(in && peekchar == '/') { //if next character is a /
        in.get(); //skip the / character
        in >> denom; //get the denominator
        valid = true;
    }
    if (in || valid) { //if we succeeded in reading
        if (denom == 0)
            denom = 1;
        numer += (whole*denom);
        input = Fraction(numer, denom);
     }
     return in;
}
ostream& operator<<(ostream& in,const Fraction& output) {
    return in << output.get_numerator() << '/' << output.get_denominator();
}
int main() {
    Fraction my_fract;
    cout << "Enter a fraction\n";
    cin >> my_fract;
    cout << "you entered " << my_fract;
}
}

您应该使用streams而不是strings 如果用户从一个想要输入/输出/ string它可以随时使用stringstream 请注意,您的定义是

istream& operator>>(istream& in,const Fraction& input)

在流语言中意味着从istream提取Fraction ,因此您的输入参数不应该是const。 另一方面,要将Fraction输出到ostream就会声明

ostream& operator<<(ostream& in,const Fraction& input) //Here const is good

另外,最后要注意的是istream/ostream是使用char作为元素和默认特征的特定实现。 更通用的实现适用于任何类型的流,运算符定义如下

template< typename Elem, typename Traits >
std::basic_istream< Elem, Traits >& operator>>(std::basic_istream< Elem, Traits >& in, Fraction& input)

template< typename Elem, typename Traits >
std::basic_ostream< Elem, Traits >& operator<<(std::basic_ostream< Elem, Traits >& out, Fraction const& output)

对于你想要为Fraction类重载的operator>>函数,而不是输入std::string ,解析它,然后尝试从解析的参数中创建一个新的Fraction对象,你应该做的就是在operator>>重载函数内解析用户输入,因为它已经可以直接访问输入流。 换句话说,你正在做的是多余的,有点令人困惑......对于Fraction对象的operator>>重载,意图应该是从整个用户输入并从该用户输入创建一个Fraction对象。在Fraction对象完成之前不要经过几个步骤。

所以你会想要这样的东西:

//set values of Fraction object through pass-by-reference
istream& operator>>(istream& in,Fraction& input);

并使用它像:

Fraction new_fraction_obj; //has only default-constructor-set values
std::cin >> new_fraction_obj;  //now will have the user-input values after call

最后,如果在尝试解析用户输入时发现它没有正确格式化,或者是错误的类型等,请通过调用ios::setstate()来设置istream对象的失败位,以便用户流可以检测到输入有问题,并且正在通过引用传递的Fraction对象处于无效状态。

标准方法是将自定义输入操作分解为成分:

std::istream & operator>>(std::istream & in, Fraction & input)  // not const!
{
  std::string token;

  if (!(in >> token)) { return in; }  // error

  int num, den;
  const bool res = parse_token(token, num, den);  // write this!

  if (!res)
  {
    in.setstate(std::ios::failbit);
    return in;
  }

  input.set(num, den); // or whatever
}

关键是编写parse_token(const std::string &, int &, int &)函数,该函数确定字符串是否表示有效分数,如果是,则将分子和分母放在两个相应的变量中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM