下列程序设计了一个分数类,其中:属性包括分子和分母;操 作包括约分、通分、加、乘、求相反数和倒数、输出等。程序中 已给出类的结构声明、函数声明和主函数,请完善全局函数、成 员函数和友元函数的设计。 #include<iostream> #include<cmath> using namespace std; class fraction { private: int m_nNumerator ; //分子 int m_nDenominator ; //分母 int gcd(int x, int y); //求最大公约数 void reduceSelf(); //约分 void makeCommonD(fraction &); //通分 public: fraction(int = 0, int b = 1); //构造函数 fraction operator+(fraction &); //两分数相加 fraction operator*(fraction &); //两分数相乘 fraction operator-(); //求相反数 friend fraction operator/(int, fraction&); //求倒数 friend ostream & operator <<( ostream & output, fraction & f); friend istream &operator >> ( istream & input, fraction & f); }; int main() { fraction f1(-3, -5), f2(-3, 5), f3(3, -7), f4; cout<<"f1 is "; cout<< f1; cout<<"f4 is "; cout<<f4; f4 = f1 + f3; cout<<"f4 = f1 + f3 : "; cout<<f4; f4 = f1 * f3; cout<<"f4 = f1 * f3 : "; cout<<f4; f4 = 1 / f2; cout<<"f4 = 1 / f2 : "; cout<<f4; f4 = -2 / f4; cout<<"f4 = -2 / f4 : "; cout<<f4; f4 = -f4; cout<<"f4 = -f4"; cout<<f4; cin>>f4; cout<<f4; return 0; }
时间: 2025-06-22 18:34:52 AIGC 浏览: 29
<think>好的,我现在需要帮助用户实现一个C++的分数类,包含约分、通分、加法、乘法、相反数和倒数等操作。首先,我得回顾一下用户的需求和提供的参考资料,确保不遗漏任何关键点。
用户提到需要实现全局函数、成员函数和友元函数。首先,分数类的基本结构应该包括分子和分母,这两个成员变量应该是私有的,通过构造函数初始化。构造函数需要考虑分母为零的情况,并且在创建分数时自动约分,比如使用gcd函数求最大公约数,然后分子分母同时除以这个数。
接下来是约分函数reduceSelf,这需要计算分子和分母的最大公约数,然后除以这个数。这里可能需要一个gcd函数,用户提供的参考资料[4]中有扩展欧几里得算法的实现,不过通常gcd可以用递归或迭代的方式实现,需要注意处理负数的情况,因为公约数一般是正数。
然后,通分函数makeCommonD,这需要找到两个分数的分母的最小公倍数,然后将两个分数转换为以这个公倍数为分母的形式。最小公倍数可以通过两数相乘除以它们的最大公约数得到,所以这里需要用到gcd函数。
运算符重载部分,加法和乘法需要实现。加法需要先通分,然后将分子相加,最后约分。乘法则是分子乘分子,分母乘分母,然后约分。这里可能需要将运算符重载为成员函数或友元函数,考虑到可能需要访问私有成员,友元函数会更方便。
相反数和倒数操作,相反数可以通过将分子取反,或者分母取反来实现,但要注意保持分母为正。倒数则是交换分子和分母,同样需要处理分母为零的情况,但分数类本身应该在构造时处理这种情况,确保分母不为零。
输入输出流的重载,需要使用友元函数,重载<<和>>操作符。输入时需要读取分子和分母,并处理可能的分母为零的情况,构造分数时会自动约分。
另外,用户提供的引用[2]中提到用C++实现有理数类,重点在于运算符重载,这可能包括加减乘除等。引用[4]中的扩展欧几里得算法可能用于求逆元,但在这里可能用于gcd的计算,不过传统的欧几里得算法已经足够。
现在需要考虑如何组织代码。首先,类的定义应该包括私有成员num和den,构造函数、约分函数、gcd函数作为辅助函数可以是静态的或者放在类外。运算符重载的话,加法可能需要友元函数,因为涉及到两个分数对象的操作,而成员函数的运算符重载左侧操作符是当前对象。
比如,operator+作为友元函数,接受两个Fraction参数,返回它们的和。乘法同理。相反数的operator-可以重载为一元运算符,作为成员函数。
通分函数可能需要作为辅助函数,或者直接在加法运算中处理。例如,当两个分数相加时,先找到公分母,调整分子,然后相加,最后约分。
测试各个函数是否正确,比如构造分数时自动约分,加法运算是否正确处理不同分母的情况,乘法是否分子分母分别相乘,结果约分是否正确。
可能遇到的问题包括分母为零的处理,负数分数的表示(比如保持分母为正,分子决定符号),以及运算符重载的返回类型是否正确,避免临时对象的构造问题。
最后,输入输出流需要正确处理格式,比如用户输入5/3,或者-2/7,输出时也以分数形式显示,且已经约分。
综上,分步骤实现各个部分,先定义类结构,再实现构造函数和约分,接着是运算符重载,最后是输入输出和辅助函数。确保每个函数都经过测试,尤其是边界情况,如分母为1,分子为0的情况。</think>以下是根据需求实现的C++分数类实现方案:
### 一、分数类基础框架
```cpp
#include <iostream>
#include <stdexcept>
using namespace std;
class Fraction {
private:
int numerator; // 分子
int denominator; // 分母
// 计算最大公约数(辅助函数)
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
public:
// 构造函数(自动约分)
Fraction(int num = 0, int den = 1) {
if (den == 0) throw invalid_argument("分母不能为0");
int common = gcd(abs(num), abs(den));
numerator = num / common;
denominator = den / common;
if (denominator < 0) { // 保持分母为正
numerator = -numerator;
denominator = -denominator;
}
}
};
```
### 二、核心成员函数实现
```cpp
// 约分函数(成员函数)
void reduceSelf() {
int common = gcd(abs(numerator), abs(denominator));
numerator /= common;
denominator /= common;
}
// 通分函数(成员函数)
static void makeCommonD(Fraction& a, Fraction& b) {
int lcm = a.denominator * b.denominator / gcd(a.denominator, b.denominator);
a.numerator *= lcm / a.denominator;
b.numerator *= lcm / b.denominator;
a.denominator = b.denominator = lcm;
}
```
### 三、运算符重载实现
```cpp
// 加法运算符重载(友元函数)
friend Fraction operator+(const Fraction& lhs, const Fraction& rhs) {
int new_den = lhs.denominator * rhs.denominator /
gcd(lhs.denominator, rhs.denominator);
int new_num = lhs.numerator * (new_den / lhs.denominator) +
rhs.numerator * (new_den / rhs.denominator);
return Fraction(new_num, new_den);
}
// 乘法运算符重载(友元函数)
friend Fraction operator*(const Fraction& lhs, const Fraction& rhs) {
return Fraction(lhs.numerator * rhs.numerator,
lhs.denominator * rhs.denominator);
}
// 一元负号运算符(成员函数)
Fraction operator-() const {
return Fraction(-numerator, denominator);
}
// 倒数运算(成员函数)
Fraction reciprocal() const {
return Fraction(denominator, numerator);
}
```
### 四、输入输出流重载
```cpp
friend ostream& operator<<(ostream& os, const Fraction& f) {
if (f.denominator == 1) return os << f.numerator;
return os << f.numerator << "/" << f.denominator;
}
friend istream& operator>>(istream& is, Fraction& f) {
int num, den;
char slash;
is >> num >> slash >> den;
f = Fraction(num, den);
return is;
}
```
### 五、应用示例
```cpp
int main() {
Fraction a(2, 4), b(3, 9);
cout << "a = " << a << endl; // 输出1/2
cout << "b = " << b << endl; // 输出1/3
Fraction c = a + b;
cout << "a + b = " << c << endl; // 输出5/6
Fraction d = a * b;
cout << "a * b = " << d << endl; // 输出1/6
}
```
阅读全文
相关推荐



















