分数类C++的重载>>
overloading >> for a fraction class C++
我试图重载一个分数类的流操作符>>。我已经创建了一个函数,可以从用户获取字符串,并将其解析为我的Fraction类的适当参数,但我不确定如何在我的>>重载函数中实现这一点。
用户可以输入三种类型的分数:1. 整数(例如5)2. 带分数(如2+4/5)3.正则分数(如1/2)
我的方法是在main函数中接受这个输入作为用户的字符串,解析它以获得有效的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 fractionn";
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 &)
函数,该函数确定字符串是否表示有效的分数,如果是,则将分子和分母放入两个各自的变量中。
- 继承函数的重载解析
- 你能重载对象变量名本身返回的内容吗
- 从父命名空间重载类型
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 重载操作程序时出错>>用于类中的字符串 memebr
- 一个关于在C++中重载布尔运算符的问题
- 不同翻译单元中不可重载的非内联函数定义
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 将重载的成员函数传递给函数模板
- c++:可变模板和函数重载
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 重载==不适用于二进制树
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 正在尝试重载二进制搜索树分配运算符
- 重载Singly Linked List中的赋值运算符
- 取消引用运算符不能重载