实验2 类和对象——基础编程1

news/2025/3/14 19:30:21/文章来源:https://www.cnblogs.com/andongni51/p/18494271

一、实验目的

 加深对类,对象的理解,能够解释类的封装,类的接口

会使用C++语法规则正确定义,实现,测试类,会使用类创建对象,并基于对象编程

针对具体问题场景,练习运用面向对象思维进行设计,合理利用C++语言特性(访问权限控制,static,friend,const),在数据共享和保护之间达到平衡

会用多文件方式组织代码

加深对C++内存资源管理技术的理解,能够解释构造函数,析构函数的用途,分析它们何时会被调用

二、实验准备

 类的抽象,设计

使用C++定义类,使用类创建对象的语法;构造/析构陈洁灵语法,用途及调用时机

类的共享与保护机制:访问权限控制,静态成员(static),友元(friend),const

多文件组织代码

 

三、实验内容

 

1. 实验任务1

代码:

 t.h

 1 #pragma once
 2 #include <string>
 3 
 4 class T{
 5     public:
 6         T(int x = 0, int y = 0);
 7         T(const T &t);
 8         T(T &&t);
 9         ~T();
10         void adjust ( int ratio );
11         void display ( )const ;
12     private:
13         int m1,m2;
14     public:
15         static int get_cnt();
16         
17     public:
18         static const std::string doc;
19         static const int max_cnt;
20     private:
21         static int cnt ;
22         
23         friend void func();
24         
25 };
26     void func();

t.cpp

 1 #include"t.h"
 2 #include<iostream>
 3 #include<string>
 4 
 5 using std::cout;
 6 using std::endl;
 7 using std::string;
 8 
 9 const std::string  T::doc{"a simple class sample"};
10 const int T :: max_cnt= 999;
11 int T::cnt = 0;
12 T ::T (int x,int y) :m1{x},m2{y}
13 {
14     ++cnt;
15     cout << "T constructor called.\n";
16 }
17 
18 T ::T (const T &t) :m1{t.m1},m2{t.m2}
19 {
20     ++cnt;
21     cout << "T copy constructor called.\n";
22 }
23 
24 
25 T ::T(T &&t):m1{t.m1},m2{t.m2}
26 {
27     ++cnt;
28     cout << "T move constructor called.\n";
29  } 
30  
31  T::~T(){
32      --cnt;
33      cout << "T destructor called.\n";
34      
35  } 
36  void T::adjust(int ratio){
37      m1*=ratio;
38      m2*=ratio;
39      
40  }
41  void T::display ()const
42  {
43      cout<<"("<<m1<<","<<"m2"<<")";
44  }
45  
46  int T::get_cnt()
47 {
48     return cnt;
49 }
50 
51 void func()
52 {
53     T t5(42);
54     t5.m2=2049;
55     cout << "t5=";t5.display();cout<<endl;
56 }

task1.cpp

 1 #include"t.h"
 2 #include<iostream>
 3 
 4 using std::cout;
 5 using std::endl;
 6 
 7 void test ( );
 8 
 9 int main()
10 {
11     test();
12     cout<<"\nmain:\n";
13     cout<<"T objects'current count:"<<T::get_cnt()<<endl;
14     
15 }
16 
17 void test()
18 {
19     cout<<"test class T:\n";
20     cout<<"T info:"<<T::doc<<endl;
21     cout<<"T objects'max count: "<<T::max_cnt<<endl;
22     cout<<"T objects'current count: "<<T::get_cnt()<<endl<<endl;
23     
24     T t1;
25     cout<<"t1 = ";t1.display();cout<<endl;
26     
27     T t2(3,4);
28     cout <<"t2 = ";t2.display();cout<<endl;
29     
30     T t3(t2);
31     t3.adjust(2);
32     cout<<"t3 = ";t3.display();cout<<endl;
33     
34     T t4(std::move(t2));
35     cout<<"t3 = ";t4.display();cout<<endl;
36     
37     cout<<"T objects'current count: "<<T::get_cnt()<<endl;
38     func();
39 }

 

 

运行截图:

 

 

 

问题回答:

 

问题一:不可以去掉t.h中最后的void func();

friend void func()不可以作为一个完整的函数声明。没有给出函数的参数列表。故还是需要在在t.h最后加上void func();

问题二:构造函数是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。

普通构造函数是创建一个对象假如有两个参数,就可以接受两个参数,如果没有参数就是使用自定义的默认值,可以是0或者其它。

复制构造函数是一个已经存在的对象创建新的对象的时候调用它,新对象与存在的对象状态相同。

移动构造函数它通过右值引用来实现资源的转移。

调用时机:调用构造函数结束后调用析构函数,析构的顺序与构造的顺序相反。

 

 问题三:

不能正确编译运行

 

2. 实验任务2

代码:

Complex.h

 1 #pragma once
 2 #include<string>
 3 
 4 class Complex{
 5     //类属性 
 6     public:
 7         static const std::string doc;
 8         Complex(double a=0,double b=0);
 9         Complex(const Complex &c);
10         
11     
12     //对象属性
13     private:
14         double real;
15         double imag;
16     //对象方法
17     public:
18          //接口:
19            const double get_real();
20            const double get_imag();
21            Complex add(const Complex& c);
22     //友元函数
23     public:
24         friend Complex add(const Complex &c1,const Complex &c2);
25         friend bool is_equal(const Complex &c1,const Complex &c2);
26         friend bool is_not_equal(const Complex &c1,const Complex &c2);
27         friend void output(const Complex &c);
28         friend double abs(const Complex &c);
29          ~Complex();
30 };
31 
32  Complex add(const Complex &c1,const Complex &c2);
33  bool is_equal(const Complex &c1,const Complex &c2);
34  bool is_not_equal(const Complex &c1,const Complex &c2);
35  void output(const Complex &c);
36  double abs(const Complex &c);

Complex.cpp

 1 #include"Complex.h"
 2 #include<iostream>
 3 #include<string>
 4 #include<cmath>
 5 
 6 
 7 using std::cout;
 8 using std::endl;
 9 using std::string;
10 
11 
12 
13 //类属性 
14 const std::string Complex::doc={"a simplified complex class"};
15 Complex::Complex(double a,double b):real(a),imag{b} {};
16 Complex::Complex(const Complex &c){
17     real=c.real;
18     imag=c.imag;
19 }
20 //接口 
21 const double Complex::get_real(){
22     return real;
23     
24 }
25 const double Complex::get_imag(){
26     return imag;
27 }
28 Complex Complex::add(const Complex& c) {
29    return Complex(real + c.real, imag + c.imag);
30 }
31 
32 
33 Complex add(const Complex &c1,const Complex &c2){
34     Complex c;
35     c.real=c1.real+c2.real;
36     c.imag=c1.imag+c2.imag;
37     return c;
38     
39 } 
40  bool is_equal(const Complex &c1,const Complex &c2){
41      if(c1.real==c2.real&&c1.imag==c2.imag)
42          return 1;
43      else
44          return 0;
45  }
46  bool is_not_equal(const Complex &c1,const Complex &c2){
47      if(c1.real!=c2.real||c1.imag!=c2.imag)
48          return 1;
49      else 
50          return 0;
51  }
52  void output(const Complex &c){
53      if(c.imag<0)
54      cout<<c.real<<c.imag<<"i";
55      else
56      cout<<c.real<<"+"<<c.imag<<"i";
57  }
58  double abs(const Complex &c){
59      return sqrt(c.real*c.real+c.imag*c.imag);
60  }
61 Complex::~Complex()=default;

 

 

运行截图:

 

 

 

 

 

 

 

3. 实验任务3

代码:

 

 1 #include <iostream>
 2 #include <complex>
 3 
 4 using std::cout;
 5 using std::endl;
 6 using std::boolalpha;
 7 using std::complex;
 8 
 9 void test() {
10     cout << "标准库模板类comple测试: " << endl;
11     complex<double> c1;
12     complex<double> c2(3, -4);
13     const complex<double> c3(3.5);
14     complex<double> c4(c3);
15 
16     cout << "c1 = " << c1 << endl;
17     cout << "c2 = " << c2 << endl;
18     cout << "c3 = " << c3 << endl;
19     cout << "c4 = " << c4 << endl;
20     cout << "c4.real = " << c4.real() << ", c4.imag = " << c4.imag() << endl;
21     cout << endl;
22 
23     cout << "复数运算测试: " << endl;
24     cout << "abs(c2) = " << abs(c2) << endl;
25     c1 += c2;
26     cout << "c1 += c2, c1 = " << c1 << endl;
27     cout << boolalpha;
28     cout << "c1 == c2 : " << (c1 == c2) << endl;
29     cout << "c1 != c3 : " << (c1 != c3) << endl;
30     c4 = c2 + c3;
31     cout << "c4 = c2 + c3, c4 = " << c4 << endl;
32 }
33 
34 int main() {
35     test();
36 }

 

 

运行截图:

 

 

 

 问题回答:

 

 

 

4. 实验任务4

代码:

Fraction.h

 1 #pragma once
 2 #include<string>
 3 
 4 class Fraction{
 5     public:
 6         static const std::string doc;
 7         Fraction(int up=1,int down=1);
 8         Fraction(const Fraction &c);
 9         
10     int get_up()const;
11     int get_down() const ;
12     Fraction negative() const;
13     static int gcd(int a,int b);
14     Fraction simplify()const;
15         
16     public:    
17     //友元函数
18         friend void output(const Fraction &c);
19         friend Fraction add(const Fraction &c1,const Fraction &c2);
20         friend Fraction sub(const Fraction &c1,const Fraction &c2);
21         friend Fraction mul(const Fraction &c1,const Fraction &c2);
22         friend Fraction div(const Fraction &c1,const Fraction &c2);
23         ~Fraction();
24     private:
25         int up;
26         int down;
27         
28          
29 };

Fraction.cpp

  1 #include"Fraction.h"
  2 #include<iostream>
  3 #include<string>
  4 #include<cmath>
  5 #include <iomanip> 
  6 
  7 using std::cout;
  8 using std::endl;
  9 using std::string;
 10 
 11 
 12 
 13 
 14 const std::string Fraction::doc={"Fraction类v 0.01版.\n目前仅支持分数对象的构造、输出、加/减/乘/除运算.\n"};
 15 Fraction::Fraction(int a,int b):up(a),down{b} {}
 16 
 17 
 18 Fraction::Fraction(const Fraction &c):up(c.up),down(c.down){
 19 }
 20 
 21 //简化分数 
 22 Fraction Fraction::simplify()const{
 23     
 24 int divisor=gcd(up,down);
 25 
 26  return Fraction(up/divisor,down/divisor);}
 27 
 28  
 29 int Fraction::get_up()const{
 30     Fraction c1=this->simplify();
 31     
 32 
 33     return c1.up;
 34 }
 35     
 36 
 37  int Fraction::get_down()const{
 38      Fraction c2=this->simplify();
 39     return c2.down;
 40     
 41 }
 42 Fraction Fraction::negative()const {
 43     
 44     return Fraction(-up,down);
 45 }
 46 
 47 int Fraction::gcd(int a,int b){
 48 
 49     while(b!=0){
 50         int temp=b;
 51         b=a%b;
 52         a=temp;
 53     }return a;
 54     
 55     
 56 }
 57 
 58 
 59 void output(const Fraction &c){
 60     
 61         
 62         if(c.down==0){cout<<"分母不能为0"; return;
 63         }
 64         if(c.up==0){cout<<0;return;}
 65     
 66             Fraction c1=c.simplify();
 67             if(c1.down==1){cout<<c.up;
 68                 
 69             }
 70             else{cout<<c1.get_up()<<"/"<<c1.get_down() ;
 71             }
 72 
 73     }
 74 
 75     
 76 
 77     
 78 
 79 
 80 Fraction add(const Fraction &c1,const Fraction &c2){
 81     
 82     Fraction c3;
 83     c3.up=c1.up*c2.down+c2.up*c1.down;
 84     c3.down=c1.down*c2.down;
 85     
 86      return c3.simplify();
 87 
 88     
 89 }
 90 
 91 Fraction sub(const Fraction &c1,const Fraction &c2){
 92     Fraction c3;
 93     c3.up=c1.up*c2.down-c2.up*c1.down;
 94     c3.down=c1.down*c2.down;
 95     
 96     return c3.simplify();
 97 }
 98     
 99 Fraction mul(const Fraction &c1,const Fraction &c2){
100     Fraction c3;
101     c3.up=c1.up*c2.up;
102     c3.down=c1.down*c2.down;
103     
104     return c3.simplify();
105 }
106 
107 
108 Fraction div(const Fraction &c1,const Fraction &c2){
109     Fraction c3;
110     c3.up=c1.up*c2.down;
111     c3.down=c1.down*c2.up;
112     
113     return c3.simplify();
114 }
115 
116 Fraction::~Fraction()=default;

 

 Fraction_test.cpp

 1 #include "Fraction.h"
 2 #include <iostream>
 3 
 4 using std::cout;
 5 using std::endl;
 6 
 7 
 8 void test1() {
 9     cout << "Fraction类测试: " << endl;
10     cout << Fraction::doc << endl << endl;
11 
12     Fraction f1(5);
13     Fraction f2(3, -4), f3(-18, 12);
14     Fraction f4(f3);
15     cout << "f1 = "; output(f1); cout << endl;
16     cout << "f2 = "; output(f2); cout << endl;
17     cout << "f3 = "; output(f3); cout << endl;
18     cout << "f4 = "; output(f4); cout << endl;
19 
20     Fraction f5(f4.negative());
21     cout << "f5 = "; output(f5); cout << endl;
22     cout << "f5.get_up() = " << f5.get_up() << ", f5.get_down() = " << f5.get_down() << endl;
23 
24     cout << "f1 + f2 = "; output(add(f1, f2)); cout << endl;
25     cout << "f1 - f2 = "; output(sub(f1, f2)); cout << endl;
26     cout << "f1 * f2 = "; output(mul(f1, f2)); cout << endl;
27     cout << "f1 / f2 = "; output(div(f1, f2)); cout << endl;
28     cout << "f4 + f5 = "; output(add(f4, f5)); cout << endl;
29 }
30 
31 void test2() {
32     Fraction f6(42, 55), f7(0, 3);
33     cout << "f6 = "; output(f6); cout << endl;
34     cout << "f7 = "; output(f7); cout << endl;
35     cout << "f6 / f7 = "; output(div(f6, f7)); cout << endl;
36 }
37 
38 int main() {
39     cout << "测试1: Fraction类基础功能测试\n";
40     test1();
41 
42     cout << "\n测试2: 分母为0测试: \n";
43     test2();
44 }

 

 

运行截图:

 

 

 

 

 

 

 

5. 实验任务5

代码:

Bank.h

 1 #ifndef ACCOUNT_H
 2 #define ACCOUNT_H
 3 
 4 class SavingsAccount{
 5     private://用户的Id ,平均数,利率,上次存款时间,计算,总和这些数是私有的。 
 6         int id;
 7         double balance;
 8         double rate;
 9         int lastDate;
10         double accumulation;
11         static double total;
12         void record(int data,double amount);//一个成员函数:用于输出 
13         double accumulate(int date)const{return accumulation+balance*(date-lastDate);}
14     public:
15     SavingsAccount(int date,int id,double rate);
16     int getId()const{return id;    }
17     double getBalance ()const {return balance;}
18     double getRate()const{return rate;}
19     static double getTotal(){return total;
20     }
21     void deposit(int date,double amount);//
22     void withdraw(int date,double amount);//
23     void settle(int date);//结算 
24     void show()const;
25 };
26 #endif 

Bank.cpp

 1 #include <iostream>
 2 #include "bank.h"
 3 #include <cmath>
 4 
 5 using namespace std;
 6  
 7 double SavingsAccount::total = 0;
 8 
 9 SavingsAccount::SavingsAccount(int date, int id, double rate): id(id), balance(0), rate(rate), lastDate(date), accumulation(0) {
10      std::cout << date << "\t#" << id << " is created" << std::endl;
11  }
12 void SavingsAccount::record(int date, double amount) {
13 accumulation = accumulate(date);
14 lastDate = date;
15 amount = floor(amount * 100 + 0.5) / 100;     //保留小数点后两位
16 balance += amount;
17 total += amount;
18 std::cout << date << "\t#" << id << "\t" << amount << "\t"<< balance << std::endl;
19 }
20  void SavingsAccount::deposit(int date, double amount) {
21 record(date, amount);
22 }
23 void SavingsAccount::withdraw(int date, double amount) {
24 if (amount > getBalance()) {
25 std::cout << "Error: not enough money" << std::endl;
26 }
27 else {
28 record(date, -amount);
29 }
30 }
31 void SavingsAccount::settle(int date) {
32 double interest = accumulate(date) * rate / 365;        //计算年息
33 if (interest != 0) 
34 record(date, interest);
35 accumulation = 0;
36 }
37 void SavingsAccount::show() const {
38 std::cout << "#" << id << "\tBalance: " << balance;
39 }

Bank_test.cpp

 1 #include "bank.h"
 2 #include <iostream>
 3 using namespace std;
 4 int main() {
 5 
 6 SavingsAccount sa0(1, 21325302, 0.015);
 7 SavingsAccount sal(1, 58320212, 0.015);
 8 
 9 sa0.deposit(5, 5000);
10 sal.deposit(25, 10000);
11 sa0.deposit(45, 5500);
12 sal.withdraw(60, 4000);
13 
14 sa0.settle(90);
15 sal.settle(90);
16 
17 sa0.show();
18 cout << endl;
19 sal.show();
20 cout << endl;
21  cout << "Total: " << SavingsAccount::getTotal() << endl;
22  return 0;
23 }

 

 

 

运行截图:

 

 

 个人银行账户管理系统使用了SavingsAccout()类封装了相关类的属性以及方法。也有不到位的地方,比如输入日期,钱数,取款数这些数据,要设置确保数据的输入是合理的,部分不能为负数。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/822641.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

宝塔环境安装phpmyadmin什么版本

在宝塔面板中安装 phpMyAdmin 时,宝塔会自动选择一个适合你当前 PHP 版本的 phpMyAdmin 版本。不过,如果你有特定的需求,可以选择安装特定版本的 phpMyAdmin。以下是详细的步骤: 1. 登录宝塔面板 打开浏览器,访问你的宝塔面板地址并登录。 2. 进入软件商店 在宝塔面板的主…

升级提示 执行SQL发生错误!错误:duplicate column name: picstitle

原因:升级过程中 SQL 语句未执行成功。解决方案:执行以下 SQL 语句:sql-- ------------------------------ -- Sqlite数据库升级脚本 -- 适用于PbootCMS 3.0.0版本升级至3.0.6 -- -------------------------------- -- 新增多图标题字段 ALTER TABLE ay_content ADD COLUMN …

重新安装SQL server失败怎么办

重新安装SQL server失败的方法有:1、确认问题原因;2、解决系统兼容性问题;3、解决硬件问题;4、解决旧版SQL Server未完全卸载的问题。在重新安装SQL Server时出现失败,首先要做的就是确认问题的原因。可能的问题包括系统兼容性问题、硬件问题、旧版SQL Server未完全卸载等…

如何进行模型并行化

型并行化是一项关键的技术,用于提高深度学习模型的性能和效率。模型并行化的关键步骤和策略,包括:1.模型归类和代表选择;2.明确并行化的目标;3.选择适当的并行化形式;4.合理安排并行化的顺序;5.深入研究模型的行为和用户的需求。模型并行化的第一步是确定要进行并行化的…

PC端的Windows软件用什么自动化测试工具好

Windows软件的自动化测试可以帮助我们在短时间内完成大量的测试任务,并发现软件中的问题。以下是一些常用的Windows软件自动化测试工具:一、Selenium;二、TestComplete;三、Ranorex;四、WinAppDriver;五、AutoIt;六、QTP(UFT);七、Eggplant。Selenium是一款非常流行的开…

为什么 C++ 能够源码级兼容C语言

## 为什么 C++ 能够源码级兼容C语言 在探讨C++为何能源码级兼容C语言的问题时,我们首先需要明确一点:C++设计之初,就将与C语言的兼容性作为核心目标之一。这种兼容性主要体现在两个方面:语法和库函数。简而言之,C++保留了C语言的语法结构和大部分库函数,同时引入了面向对…

Error:Kotlin: Module was compiled with an incompatible version of Kotlin. Th

Error:Kotlin: Module was compiled with an incompatible version of Kotlin. Th本文来自博客园,作者:VipSoft 转载请注明原文链接:https://www.cnblogs.com/vipsoft/p/18507853

2024-2025-1 20241428 《计算机基础与程序设计》第5周学习总结

作业信息 |这个作业要求在哪里|<作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)| |这个作业的目标|Pep/9虚拟机 机器语言与汇编语言 算法与伪代码 测试:黑盒,白盒| |作业正文|https://i.cnblogs.com/posts/edit | 教材学习内容总结 算法的特性: 有穷性…

js逆向实战之某天下登陆参数pwd加密逻辑

声明:本篇文章仅用于知识分享,不得用于其它用途 网址:https://passport.fang.com/ 加密逻辑随便输入用户名和密码,看触发的数据包。可以看到pwd明显被加密了,全局搜索url中的关键字loginwithpwdStrong.api。只有两处,全部打上断点,重新登录一次,看触发哪个。触发了jque…

读数据工程之道:设计和构建健壮的数据系统21数据获取

数据获取1. 数据获取 1.1. 数据获取是将数据从一个地方移动到另一个地方的过程1.1.1. 数据获取与系统内部获取是不同的1.2. 数据获取是数据工程生命周期中将数据从源系统移入存储的一个中间步骤 1.3. 数据集成则是将来自不同来源系统的数据组合到一个新的数据集 1.4. 数据获取的…

Windows Server 2022 中文版、英文版下载 (updated Oct 2024)

Windows Server 2022 中文版、英文版下载 (updated Oct 2024)Windows Server 2022 中文版、英文版下载 (updated Oct 2024) Windows Server 2022 x64, Version 21H2 请访问原文链接:https://sysin.org/blog/windows-server-2022/ 查看最新版。原创作品,转载请保留出处。 作者…

Windows 11 version 24H2 LTSC 2024 中文版、英文版 (x64、ARM64) 下载 (updated Oct 2024)

Windows 11 version 24H2 & LTSC 2024 中文版、英文版 (x64、ARM64) 下载 (updated Oct 2024)Windows 11 version 24H2 & LTSC 2024 中文版、英文版 (x64、ARM64) 下载 (updated Oct 2024) Windows 11, version 24H2,企业版 arm64 x64 请访问原文链接:https://sysin.…