面向对象程序设计实验——编写Rational类
实验任务与要求
编写一个表示有理数的类Rational。(有理数就是分数,包含分子与分母,均为整数)。要求:
1)定义一个命名空间Numeric,在该空间中定义类Rational;
2)编写默认构造函数,构造一个有理数0;
3)编写带参数列表的构造函数Rational (int, int ),要求使用初始化列表;
4)编写复制构造函数;
5)编写赋值操作=;
6)编写四个友元函数add、sub、mul、div,对两个Rational对象表示的有理数分别进行
相加、相减、相乘、相除运算;
(例:Rational x(1,2),y(1,3);分别表示有理数,则Rational z = add(x,y);之后,z表示)
7)重载上述四个函数,实现有理数与整数的相加、相减、相乘、相除运算;
(例:Rational x(1,2);表示有理数,则 Rational z = add(x,1),之后,z表示)
8)编写成员函数getValue(),返回用浮点数表示的有理数,要求写成常函数。
(例:Rational x(1,2);表示有理数,则x.getValue()返回0.5)
9)编写友元函数lessThan,比较两个有理数的大小,返回bool类型。
(例:Rational x(1,2),y(1,3);则bool b = lessThan(x,y);之后b为false)
10)编写main函数,使用using namespace Numeric;来访问Numeric::Rational类。
编写代码测试Rational类。
11)在main函数中,随机生成10个有理数,形成一个有理数数组,
并利用lessThan函数以及任意一种排序算法,对这10个有理数进行从小到大排序,输出排序结果。
代码解析
定义一个命名空间Numeric
下面展示代码片段 Numeric
。
// 命名空间内定义类及类的成员函数
// 本文简化设计,将函数体一同编写进类中
// 为代码清晰,可自定义头文件
namespace Numeric {
/*表示有理数的类*/
class Rational {
public:
// 默认构造函数,构造一个有理数0
Rational() :numerator(0), denominator(1) {}
// 带参数列表的构造函数,要求使用初始化列表
Rational(int _a, int _b) :numerator(_a), denominator(_b) {}
// 复制构造函数
Rational(const Rational& rational) {}
// 编写赋值操作 =
Rational& operator=(const Rational& rational) {}
private:
int numerator; // 分子
int denominator; // 分母
public:
// 分数化简,参数为一个Rational对象
Rational& fractionSimplify() {}
// 有理数相加,参数为两个Rational对象
friend Rational add(const Rational& x, const Rational& y) {}
// 重载函数,实现有理数与整数的相加
friend Rational add(const Rational& x, const int y) {}
// 有理数相减,参数为两个Rational对象,
friend Rational sub(const Rational& x, const Rational& y) {}
// 重载函数,实现有理数与整数的相减
friend Rational sub(const Rational& x, const int y) {}
// 有理数相乘,参数为两个Rational对象,
friend Rational mul(const Rational& x, const Rational& y) {}
// 重载函数,实现有理数与整数的相乘
friend Rational mul(const Rational& x, const int y) {}
// 有理数相除,参数为两个Rational对象,
friend Rational div(const Rational& x, const Rational& y) {}
// 重载函数,实现有理数与整数的相除
friend Rational div(const Rational& x, const int y) {}
// 返回用浮点数表示的有理数,参数为两个Rational对象,要求写成常函数
float getValue()const {}
// 比较两个有理数的大小,参数为两个Rational对象,返回bool类型
friend bool lessThan(const Rational x, const Rational y) {}
};
}
Rational类的成员变量
下面展示代码片段 。
private:
int numerator; // 分子
int denominator; // 分母
编写默认构造函数
下面展示代码片段 Rational()
。
直接初始化,为避免除零异常,分母初始化为1
// 默认构造函数,构造一个有理数0
Rational() :numerator(0), denominator(1) {}
// 带参数列表的构造函数,要求使用初始化列表
Rational(int _a, int _b) :numerator(_a), denominator(_b) {}
编写复制构造函数
下面展示代码片段。
Rational(const Rational& rational) {
numerator = rational.numerator;
denominator = rational.denominator;
}
编写赋值操作=
下面展示代码片段。
Rational& operator=(const Rational& rational) {
if (this != &rational) {
numerator = rational.numerator;
denominator = rational.denominator;
}
return *this;
}
分数化简
用于简化后续计算。
下面展示代码片段。
Rational& fractionSimplify() {
int up, under;
if (this->getValue() > 1) { // 假分数
up = this->denominator;
under = this->numerator;
}
else {
up = this->numerator;
under = this->denominator;
}
while (under % up != 0) {
int temp = under;
under = up;
up = temp % up;
}
this->numerator /= up;
this->denominator /= up;
return *this;
}
编写友元函数
以add为例。
下面展示代码片段 add
。
friend Rational add(const Rational& x, const Rational& y) {
int _numerator = x.numerator * y.denominator + y.numerator * x.denominator;
int _denominator = x.denominator * y.denominator;
return Rational(_numerator, _denominator).fractionSimplify();
}
编写重载函数
以add为例。
下面展示代码片段 add
。
friend Rational add(const Rational& x, const int y) {
int _numerator = x.numerator + y * x.denominator;
int _denominator = x.denominator;
return Rational(_numerator, _denominator).fractionSimplify();
}
main函数测试
下面展示代码。
int main(void) {
using namespace Numeric;
std::cout << name << " " << ID << std::endl;
int numY = 2;
Rational testX(1, 2);
Rational testY(3, 4);
Rational testOut;
std::cout << "两个有理数算数运算:" << testX.getValue() << " , " << testY.getValue() << std::endl;
testOut = add(testX, testY);
std::cout << "Add reasult = " << testOut.getValue() << std::endl;
testOut = sub(testX, testY);
std::cout << "Sub reasult = " << testOut.getValue() << std::endl;
testOut = div(testX, testY);
std::cout << "Div reasult = " << testOut.getValue() << std::endl;
testOut = mul(testX, testY);
std::cout << "Mul reasult = " << testOut.getValue() << std::endl;
std::cout << "有理数与常数算数运算:" << testX.getValue() << " , " << numY << std::endl;
testOut = add(testX, numY);
std::cout << "Add reasult = " << testOut.getValue() << std::endl;
testOut = sub(testX, numY);
std::cout << "Sub reasult = " << testOut.getValue() << std::endl;
testOut = div(testX, numY);
std::cout << "Div reasult = " << testOut.getValue() << std::endl;
testOut = mul(testX, numY);
std::cout << "Mul reasult = " << testOut.getValue() << std::endl;
std::srand(int(time(0)));
std::vector<Rational> rationals;
for (int i = 0; i < 10; ++i) { // 随机生成10个有理数,形成一个有理数数组
int _numerator = (int)std::rand() % 10 + 1;
int _denominato = (int)std::rand() % 10 + 1;
Rational gener(_numerator, _denominato);
rationals.push_back(gener);
}
for (unsigned int i = 0; i < rationals.size() - 1; ++i) { // 冒泡排序,升序
for (unsigned int j = 0; j < rationals.size() - 1 - i; ++j)
if (!lessThan(rationals[j], rationals[j + 1])) {
Rational temp = rationals[j];
rationals[j] = rationals[j + 1];
rationals[j + 1] = temp;
}
}
std::cout << "排序结果:" << std::endl;
for (unsigned int i = 0; i < rationals.size(); ++i) { // 输出排序结果
std::cout << rationals[i].getValue() << std::ends;
}
return 0;
}
测试截图
写在最后
本文作者刚开始学C++,如有问题或不对之处,欢迎指摘
代码仅供参考,问题实现范式不唯一,希望能给读者带来启发
版权声明:本文为weixin_44148685原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。