C++:专题六实验(运算符重载、友元函数)
Tips:如果你有看不懂的地方,欢迎<私信我> 或者<百度搜索c++菜鸟教程>,提问是解决问题的最好办法!
文章目录
- C++:专题六实验(运算符重载、友元函数)
- Tips:如果你有看不懂的地方,欢迎<私信我> 或者<百度搜索c++菜鸟教程>,提问是解决问题的最好办法!
- 实验目的:
- 实验内容:
- (一)` 任何有理数都可以表示为“分子/分母”的方式,其中分子、分母都是整数。实现一个有理数类,为这个有理数类重载四则运算(+、-、*、/)和所有的比较逻辑运算符(==、!=、>=、>、<=、<)所有重载均以类的成员函数的方式实现。`
- (二)`定义一个表示复数的Complex类,包含实部和虚部的两个属性。在类的外部以友元函数的形式重载+、-、*等运算符。要求在数函数中给出测试程序,运算结果要符合数学意义。接下来,为其重载输入输出流。以使用cin和cout关键字对Complex的对象进行输入输出。`
- (三)`实现一个时钟类Clock。包含时、分、秒三个属性。重载其赋值运算符(=)和自增运算符(自减运算符因为没有实际意义,本题中不予实现)。并给出测试语句证明其正确性。`
实验目的:
- 学习类的运算符重载的基本方法
- 掌握常见的算术运算符和逻辑运算符的重载的方法,包括以成员函数方式重载和非成员方式重载两种方法;
- 学习输入输出流运算符的重载,理解其重载过程中的参数、返回值和重载方式;
- 学习赋值运算符、下标运算符的重载方法,学习一元求反运算符的重载方法及其与减法运算符重载的区别,学习前置/后置自增/自减运算符的重载方法及运用
实验内容:
- 任何有理数都可以表示为“分子/分母”的方式,其中分子、分母都是整数。实现一个有理数类,为这个有理数类重载四则运算(+、-、*、/)和所有的比较逻辑运算符(==、!=、>=、>、<=、<)所有重载均以类的成员函数的方式实现。
- 定义一个表示复数的Complex类,包含实部和虚部的两个属性。在类的外部以友元函数的形式重载+、-、*等运算符。要求在数函数中给出测试程序,运算结果要符合数学意义。接下来,为其重载输入输出流。以使用cin和cout关键字对Complex的对象进行输入输出。
- 实现一个时钟类Clock。包含时、分、秒三个属性。重载其赋值运算符(=)和自增运算符(自减运算符因为没有实际意义,本题中不予实现)。并给出测试语句证明其正确性。
(一)任何有理数都可以表示为“分子/分母”的方式,其中分子、分母都是整数。实现一个有理数类,为这个有理数类重载四则运算(+、-、*、/)和所有的比较逻辑运算符(==、!=、>=、>、<=、<)所有重载均以类的成员函数的方式实现。
#include <iostream>
#include <cstring>
using namespace std;
class Rational
{
private:
int numerator, denominator; //分子和分母
public:
Rational(int n = 1, int d = 1); //构造函数(注意需要有默认参数)
void simplify();//最简化分数函数
string show();//输出分数
Rational operator+(const Rational& num);//此处参见知识点:运算符的重载
Rational operator-(const Rational& num);
Rational operator*(const Rational& num);
Rational operator/(const Rational& num);
bool operator >(const Rational& num);//此处参见知识点:关系运算符的重载
bool operator <(const Rational& num);
bool operator >=(const Rational& num);
bool operator <=(const Rational& num);
bool operator ==(const Rational& num);
bool operator !=(const Rational& num);
};
Rational::Rational(int n, int d) //定义构造函数
{
numerator = n, denominator = d;
simplify();
}
void Rational::simplify()//定义最简化函数
{
bool isNegative = false;//判断是否为负分数
if(numerator < 0)//分数小于零时,把分数去负号
{
isNegative = true;
numerator = -numerator;
}
int t = numerator <= denominator ? numerator : denominator;
if(numerator == 0)//有理数为0
{
denominator = 1; //分母设为1,便于运算与输出
}
if(numerator > 0)//分数大于零时
{
for(int i = t; i >= 2; i--)
if(numerator % i == 0 && denominator % i == 0)
numerator /= i, denominator /= i;
}
if(isNegative)//分数小于零,再添上负号
numerator = -numerator;
}
string Rational::show()//定义输出函数
{
simplify();
if(denominator != 1)
return " " + to_string(numerator) + "/" + to_string(denominator) + " ";
else
return " " + to_string(numerator) + " ";
}
Rational Rational:: operator+(const Rational& num)//重新定义加法
{
Rational r;
//注意,这里写this->numerator(this是个指针,指向是调用此函数的对象)或者直接写numerator,不用r.numerator,否则会使用局部变量r的值
r.numerator = this->numerator * num.denominator + num.numerator * this->denominator;
r.denominator = this->denominator * num.denominator;
r.simplify();
return r;
}
Rational Rational:: operator-(const Rational& num)//重新定义减法
{
Rational r;
r.numerator = this->numerator * num.denominator - num.numerator * this->denominator;
r.denominator = this->denominator * num.denominator;
r.simplify();
return r;
}
Rational Rational:: operator*(const Rational& num)//重新定义乘法
{
Rational r;
r.numerator = this->numerator * num.numerator;
r.denominator = this->denominator * num.denominator;
r.simplify();
return r;
}
Rational Rational:: operator/(const Rational& num)//重新定义除法
{
Rational r;
r.numerator = this->numerator * num.denominator;
r.denominator = this->denominator * num.numerator;
r.simplify();
return r;
}
bool Rational:: operator >(const Rational& num)
{
if(numerator * num.denominator - denominator * num.numerator > 0)
return true;
else
return false;
}
bool Rational:: operator <(const Rational& num)
{
if(this->numerator * num.denominator - this->denominator * num.numerator < 0)
return true;
else
return false;
}
bool Rational:: operator >=(const Rational& num)
{
if(this->numerator * num.denominator - this->denominator * num.numerator >= 0)
return true;
else
return false;
}
bool Rational:: operator <=(const Rational& num)
{
if(this->numerator * num.denominator - this->denominator * num.numerator <= 0)
return true;
else
return false;
}
bool Rational:: operator ==(const Rational& num)
{
if(this->numerator * num.denominator - this->denominator * num.numerator == 0)
return true;
else
return false;
}
bool Rational:: operator !=(const Rational& num)
{
if(this->numerator * num.denominator - this->denominator * num.numerator != 0)
return true;
else
return false;
}
int main()
{
int a1, a2, b1, b2;
cout << "请输入有理数a(分子 分母格式):" << endl;
cin >> a1 >> a2;
cout << "请输入有理数b(分子 分母格式):" << endl;
cin >> b1 >> b2;
Rational a(a1, a2);
Rational b(b1, b2);
Rational c1 = a + b;
Rational c2 = a - b;
Rational c3 = a * b;
Rational c4 = a / b;
cout << "输出结果如下:" << endl;
cout << a.show() << "+" << b.show() << "=" << c1.show() << endl;
cout << a.show() << "-" << b.show() << "=" << c2.show() << endl;
cout << a.show() << "*" << b.show() << "=" << c3.show() << endl;
cout << a.show() << "/" << b.show() << "=" << c4.show() << endl;
string o[6] = {">", "<", ">=", "<=", "==", "!="};
string t[6];
for(int i = 0; i < 6; i++)
t[i] = "false";
if(a > b)
t[0] = "true";
if(a < b)
t[1] = "true";
if(a >= b)
t[2] = "true";
if(a <= b)
t[3] = "true";
if(a == b)
t[4] = "true";
if(a != b)
t[5] = "true";
for(int i = 0; i < 6; i++)
cout << a.show() << o[i] << b.show() << "is " << t[i] << endl;
return 0;
}
(二)定义一个表示复数的Complex类,包含实部和虚部的两个属性。在类的外部以友元函数的形式重载+、-、*等运算符。要求在数函数中给出测试程序,运算结果要符合数学意义。接下来,为其重载输入输出流。以使用cin和cout关键字对Complex的对象进行输入输出。
#include <iostream>
using namespace std;
class Complex
{
private:
double real, image;
public:
Complex(double r, double i);
//知识点:运算符的重载、友元函数
friend Complex operator +(Complex a, Complex b);
friend Complex operator -(Complex a, Complex b);
friend Complex operator *(Complex a, Complex b);
friend Complex operator /(Complex a, Complex b);
//知识点:输入输出运算符的重载:
friend ostream &operator <<(ostream &output, const Complex &C);
friend istream &operator >>(istream &input, Complex &C);
};
Complex::Complex(double r = 0, double i = 0)
{
real = r, image = i;
}
Complex operator +(Complex a, Complex b)
{
Complex c;
c.real = a.real + b.real;
c.image = a.image + b.image;
return c;
}
Complex operator -(Complex a, Complex b)
{
Complex c;
c.real = a.real - b.real;
c.image = a.image - b.image;
return c;
}
Complex operator *(Complex a, Complex b)
{
Complex c;
c.real = a.real * b.real - a.image * b.image;
c.image = a.real * b.image + a.image * b.real;
return c;
}
Complex operator /(Complex a, Complex b)
{
Complex c;
c.real = (a.real * b.real + a.image * b.image) / (b.real * b.real + b.image * b.image);
c.image = (a.image * b.real - a.real * b.image) / (b.real * b.real + b.image * b.image);
return c;
}
ostream &operator <<(ostream &output, const Complex &C)
//为啥加上const?
//我们不希望在这个函数中对用来进行赋值的“原版”做任何修改。函数加上const后缀的作用是表明函数本身不会修改类成员变量。
//加上const,对于const和非const的实参,函数都能接受;如果不加,就只能接受非const的实参。
{
if(C.real != 0)
{
if(C.image > 0)
output << C.real << "+" << C.image << "i";
else if(C.image < 0)
output << C.real << C.image << "i";
else
output << C.real;
}
else
{
if(C.image != 0)
output << C.image << "i";
else
output << 0;
}
return output;
}
istream &operator >>(istream &input, Complex &C)//为啥这里不用const?
{
input >> C.real >> C.image;
return input;
}
int main()
{
Complex x, y;
cout << "请输入复数x:";
cin >> x;
cout << "请输入复数y:";
cin >> y;
cout << "x + y = " << x + y << endl;
cout << "x - y = " << x - y << endl;
cout << "x * y = " << x*y << endl;
cout << "x / y = " << x / y << endl;
return 0;
}
(三)实现一个时钟类Clock。包含时、分、秒三个属性。重载其赋值运算符(=)和自增运算符(自减运算符因为没有实际意义,本题中不予实现)。并给出测试语句证明其正确性。
#include <iostream>
#include <iomanip>
using namespace std;
class Clock
{
public:
int hour, minute, second;
Clock(int h, int m, int s);
Clock run();//定义一个加一秒的函数
void show();//定义一个打印变量的函数
//知识点:自增++和自减--运算符的重载
Clock operator++();//++i,前置形式
Clock operator++(int);//i++,后置形式,这里的int没有意义,只是用来区分前置和后置形式
//Clock operator--();
//Clock operator--(int);
//知识点:赋值运算符的重载
void operator=(const Clock &C);
};
Clock::Clock(int h = 0, int m = 0, int s = 0)
{
hour = h, minute = m, second = s;
}
Clock Clock::run()
{
++second;
if(second == 60)
{
++minute;
second -= 60;
if(minute == 60)
{
++hour;
minute -= 60;
if(hour == 24)
hour -= 24;
}
}
return *this;
}
void Clock::show()
{
cout << setw(2) << setfill('0') << hour << ":" << setw(2) << setfill('0') << minute << ":" << setw(2) << setfill('0') << second << endl;
}
//前置++指先实现对象的自增,再返回自增后的对象
Clock Clock::operator++()//重载前缀++
{
return run();
}
//后置++指先返回对象本身,再实现对象的自增
Clock Clock::operator++(int)//重载后缀++
{
Clock C = *this;
this->run();
return C;
}
void Clock::operator=(const Clock &C)
{
this->hour = C.hour;
this->minute = C.minute;
this->second = C.second;
}
int main()
{
int h, m, s;
cout << "请输入一个时间(时 分 秒):";
cin >> h >> m >> s;
Clock A(h, m, s);
Clock B;
Clock C;
Clock D;
cout << "Clock A: ", A.show();
cout << "Clock B: ", B.show();
cout << "Clock C: ", C.show();
cout << "Clock D: ", D.show();
cout << endl;
B = ++A;
cout << "B = ++A;" << endl;
cout << "Clock A: ", A.show();
cout << "Clock B: ", B.show();
cout << endl;
C = A++;
cout << "C = A++;" << endl;
cout << "Clock A: ", A.show();
cout << "Clock C: ", C.show();
cout << endl;
D = A;
cout << "D = A;" << endl;
cout << "Clock A: ", A.show();
cout << "Clock D: ", D.show();
cout << endl;
return 0;
}
友情提示:《实验一》中代码如果使用低版本codeblocks运行,编译时可能会出现to_string函数报错。此时请使用其他编译器或高版本codeblocks运行(博主使用20.03版本 点击下载 丨安装说明)。