簡體   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