C/C++ 类:构造与析构函数 有理数运算实例
before|正文之前:
c++实验代码及学习笔记(五)
你好! 这是一个高程实验课的代码记录及学习笔记。我将记录一些重要的知识点、易错点。但是作为大学生,水平很低,敬请指点教导、优化代码。
1问题
首先我们来看一下问题
这次的问题乍一看有些云里雾里,让人不知所云。我们索性把第二问忽略,只看第一问。设计一个有理数类,表示成分数,进行两个有理数的加减乘除运算。
首先,我们知道,一切有理数都能表示成分数,那么我们要设计的类,就要具有分数的特性:数据成员是分子和分母,成员函数是分数的表示、运算如化简、四则运算等等。这个类可以创造各种各样的分数对象。
其次这个问题中我们不可避免用到构造函数(析构主要是下一问)我们会对构造函数稍作讲解。
2思路
类的设计
类:Class Rational
成员数据:私有
- 分子 _num
- 分母 _den
成员函数:公开
- 默认构造函数:初始化分数
- 设定分数值(带参无返回)
- 输出成x/y的分数形式(无返回)
- 化简分数(无返回)
- 加减乘除四则运算(有理数类型 带参有返回)
构造函数与析构函数
参考文章:C++默认构造函数与构造函数
构造函数:C++用于构建类的新对象时需要调用的函数,该函数无返回类型!(注意:是“无”! 不是空!(void))。
默认构造函数:未提供显式初始值时,用来创建对象的构造函数。
C++语言特性,系统在创建类的新对象的时候会自动调用构造函数。而析构函数呢,就是这个对象被销毁的时候自动调用析构函数。一个伴随生,一个伴随灭。
那么我们就可以用构造函数和析构函数搞事情,非常方便。比如析构函数可以用来回收内存,构造函数可以用来初始化对象。
就算你不特意写构造函数呢,系统也会自己悄悄写个默认构造函数就不给你显示出来。毕竟生来就有。
然后当你要写构造函数的时候呢,除非自己写个默认构造函数,必须在你的构造函数前面加上一个默认构造函数,不然报错。这就是傲娇吧(`へ´*)ノ
那么默认特殊在哪里呢?我们又该怎么写构造函数呢?
class testClass
{
public:
testClass(); /* 默认构造函数 */
testClass(int a, char b); /* 构造函数 */
testClass(int a=10,char b='c'); /* 默认构造函数 */
~textClass(); /*析构函数*/
private:
int m_a;
char m_b;
};
如果程序猿没有定义任何构造函数,则编译器会自动定义默认构造函数,其形式如 testClass() {}
定义默认构造函数有两种方式,如上述代码展示的,一是定义一个无参的构造函数,二是定义所有参数都有默认值的构造函数 ;
一个类必须有且只能有一个默认构造函数!
析构函数无参无返回值
3题目详解
参考代码:百度知道:c++定义一个有理数类……
C++实现有理数类加减乘除
设计类:
#include<iostream>
using namespace std;
class Rational
{
private:
int num, den;//分子,分母
public:
Rational(int num = 0,int den = 1)//初始分子分母 默认构造函数
{}
void Set(int x, int y)//设定分子分母
{
num = x;
den = y;
}
void print()//输出x/y
{
if (num == 0 || den == 0) { }
else {
cout << num << "/" << den << endl;
}
}
void simple()//化简:使用辗转相除法化简分数
{
int temp;
int x = num, y = den;
while (temp = x % y)//辗转相除法
{
x = y;
y = temp;
}
den /= y;
num /= y;
if (den < 0) {
den = -den;
num = -num;
}
}
...
}
int main()
{
Rational r1;
...
return 0;
}
这是基本的构架,四则运算需要注意的是,我们要返回的结果也是有理数,所以用【有理数】这个函数类型,传入两个要运算的有理数的地址
加:分子=第一个分子乘第二个分母+第二个分子乘第一个分母
分母=第一个分母乘第二个分母
减、乘、除同理
需注意除不能让第二个分数=0
public:
Rational plus(const Rational &r1, const Rational &r2)
{
Rational r;
r.num = r1.num*r2.den + r2.num*r1.den;
r.den = r1.den*r2.den;
r.simple();
return r;
}
Rational sub(const Rational &r1, const Rational &r2)
{
Rational r;
r.num = r1.num*r2.den - r2.num*r1.den;
r.den = r1.den*r2.den;
r.simple();
return r;
}
Rational mult(const Rational &r1, const Rational &r2)
{
Rational r;
r.num = r1.num*r2.num;
r.den = r1.den*r2.den;
r.simple();
return r;
}
Rational div(const Rational &r1, const Rational &r2)
{
Rational r;
if (r2.num == 0 || r2.den == 0)
{
cout << "分母不得为0" << endl;
}
else {
r.num = r1.num*r2.den;
r.den = r2.num*r1.den;
}
r.simple();
return r;
}
4代码实现
#include<iostream>
using namespace std;
int objCount = 0;
class Rational
{
private:
int num, den;//分子,分母
public:
Rational(int num = 0,int den = 1)//初始分子分母 默认构造函数
{
cout << "Count" << endl;
objCount += 1;
}
~Rational()
{
cout << "Discount" << endl;
objCount -= 1;
}
void Set(int x, int y)//设定分子分母
{
num = x;
den = y;
}
void print()//输出x/y
{
if (num == 0 || den == 0) {
}
else {
cout << num << "/" << den << endl;
}
}
double ToDec()//转换成小数
{
double dec = num / den;
return dec;
}
void simple()//化简
{
int temp;
int x = num, y = den;
while (temp = x % y)//辗转相除法
{
x = y;
y = temp;
}
den /= y;
num /= y;
if (den < 0) {
den = -den;
num = -num;
}
}
public:
Rational plus(const Rational &r1, const Rational &r2)
{
Rational r;
r.num = r1.num*r2.den + r2.num*r1.den;
r.den = r1.den*r2.den;
r.simple();
return r;
}
Rational sub(const Rational &r1, const Rational &r2)
{
Rational r;
r.num = r1.num*r2.den - r2.num*r1.den;
r.den = r1.den*r2.den;
r.simple();
return r;
}
Rational mult(const Rational &r1, const Rational &r2)
{
Rational r;
r.num = r1.num*r2.num;
r.den = r1.den*r2.den;
r.simple();
return r;
}
Rational div(const Rational &r1, const Rational &r2)
{
Rational r;
if (r2.num == 0 || r2.den == 0)
{
cout << "分母不得为0" << endl;
}
else {
r.num = r1.num*r2.den;
r.den = r2.num*r1.den;
}
r.simple();
return r;
}
};
int main()
{
Rational r1, r2;
Rational r;
int num1, den1, num2, den2;
cout << "请设定分子分母" << endl;
cin >> num1 >> den1;
r1.Set(num1, den1);
r1.print();
cout << "请设定分子分母" << endl;
cin >> num2 >> den2;
r2.Set(num2, den2);
r2.print();
r = r.plus(r1, r2);
r.print();
r = r.sub(r1, r2);
r.print();
r = r.mult(r1, r2);
r.print();
r = r.div(r1, r2);
r.print();
getchar();
getchar();
return 0;
}
5最终效果
(在构造和析构函数下我写了输出语句,每创建一个新对象输出count,每销毁一个输出discount)
今天的讲解到此结束,如有问题及时交流,感谢阅读,下台鞠躬!