实验三

实验任务1

(1)代码部分

 1 //button.hpp
 2 #pragma once
 3 
 4 #include <iostream>
 5 #include <string>
 6 
 7 using std::string;
 8 using std::cout;
 9 
10 // 按钮类
11 class Button {
12 public:
13     Button(const string &text);
14     string get_label() const;
15     void click();
16 
17 private:
18     string label;
19 };
20 
21 Button::Button(const string &text): label{text} {
22 }
23 
24 inline string Button::get_label() const {
25     return label;
26 }
27 
28 void Button::click() {
29     cout << "Button '" << label << "' clicked\n";
30 }
31 //winodw.hpp
32 #pragma once
33 #include "button.hpp"
34 #include <vector>
35 #include <iostream>
36 
37 using std::vector;
38 using std::cout;
39 using std::endl;
40 
41 // 窗口类
42 class Window{
43 public:
44     Window(const string &win_title);
45     void display() const;
46     void close();
47     void add_button(const string &label);
48 
49 private:
50     string title;
51     vector<Button> buttons;
52 };
53 
54 Window::Window(const string &win_title): title{win_title} {
55     buttons.push_back(Button("close"));
56 }
57 
58 inline void Window::display() const {
59     string s(40, '*');
60 
61     cout << s << endl;
62     cout << "window title: " << title << endl;
63     cout << "It has " << buttons.size() << " buttons: " << endl;
64     for(const auto &i: buttons)
65         cout << i.get_label() << " button" << endl;
66     cout << s << endl;
67 }
68 
69 void Window::close() {
70     cout << "close window '" << title << "'" << endl;
71     buttons.at(0).click();
72 }
73 
74 void Window::add_button(const string &label) {
75     buttons.push_back(Button(label));
76 }
77 //task1.cpp
78 #include "window.hpp"
79 #include <iostream>
80 
81 using std::cout;
82 using std::cin;
83 
84 void test() {
85     Window w1("new window");
86     w1.add_button("maximize");
87     w1.display();
88     w1.close();
89 }
90 
91 int main() {
92     cout << "用组合类模拟简单GUI:\n";
93     test();
94 }
View Code

 

(2)运行结果

 

(3)

问题一:

自定义了两个类:Window和Button;使用了标准库中的string类和vector类;Button类中使用了string类,Window类中使用了Button类,string类和vector类;

问题二:

不适合再添加const或inline,剩下的函数不会修改类内成员数据无需加const,inline使用太多会使代码膨胀,并且剩下函数执行时间与调用时间差别不大,使用inline收益小;

问题三:

创建一个长度为40的‘*’号字符串s;

 

实验任务2

(1)代码部分

 1 //task2.cpp
 2 #include <iostream>
 3 #include <vector>
 4 
 5 using namespace std;
 6 
 7 void output1(const vector<int> &v) {
 8     for(auto &i: v)
 9         cout << i << ", ";
10     cout << "\b\b \n";
11 }
12 
13 void output2(const vector<vector<int>> v) {
14     for(auto &i: v) {
15         for(auto &j: i)
16             cout << j << ", ";
17         cout << "\b\b \n";
18     }
19 }
20 
21 void test1() {
22     vector<int> v1(5, 42);
23     const vector<int> v2(v1);
24 
25     v1.at(0) = -999;
26     cout << "v1: ";  output1(v1);
27     cout << "v2: ";  output1(v2);
28     cout << "v1.at(0) = " << v1.at(0) << endl;
29     cout << "v2.at(0) = " << v2.at(0) << endl;
30 }
31 
32 void test2() {
33     vector<vector<int>> v1{{1, 2, 3}, {4, 5, 6, 7}};
34     const vector<vector<int>> v2(v1);
35 
36     v1.at(0).push_back(-999);
37     cout << "v1: \n";  output2(v1);
38     cout << "v2: \n";  output2(v2);
39 
40     vector<int> t1 = v1.at(0);
41     cout << t1.at(t1.size()-1) << endl;
42     
43     const vector<int> t2 = v2.at(0);
44     cout << t2.at(t2.size()-1) << endl;
45 }
46 
47 int main() {
48     cout << "测试1:\n";
49     test1();
50 
51     cout << "\n测试2:\n";
52     test2();
53 }
View Code

 

(2)运行结果

 

(3)

问题一:

创建一个长度为5的整型vector数组:v1,将所有元素初始化为42;以v1为原型复制构造v2;将v1第一个元素改为-999;

问题二:

创建一个二维的vector数组v1,元素类型为int并初始化;以v1为原型复制构造v2;在v1的第一行后面添加元素-999;

问题三:

将v1的第一行元素复制给t1;打印出t1的最后一个元素;将v2的第一行元素复制给t2;打印出t2的最后一个元素;

问题四:

vector的复制构造函数是深复制;不需要;

 

实验任务三

(1)代码部分

  1 //vectorInt.hpp
  2 #pragma once
  3 
  4 #include <iostream>
  5 #include <cassert>
  6 
  7 using std::cout;
  8 using std::endl;
  9 
 10 // 动态int数组对象类
 11 class vectorInt{
 12 public:
 13     vectorInt(int n);
 14     vectorInt(int n, int value);
 15     vectorInt(const vectorInt &vi);
 16     ~vectorInt();
 17 
 18     int& at(int index);
 19     const int& at(int index) const;
 20 
 21     vectorInt& assign(const vectorInt &v);
 22     int get_size() const;
 23 
 24 private:
 25     int size;
 26     int *ptr;       // ptr指向包含size个int的数组
 27 };
 28 
 29 vectorInt::vectorInt(int n): size{n}, ptr{new int[size]} {
 30 }
 31 
 32 vectorInt::vectorInt(int n, int value): size{n}, ptr{new int[size]} {
 33     for(auto i = 0; i < size; ++i)
 34         ptr[i] = value;
 35 }
 36 
 37 vectorInt::vectorInt(const vectorInt &vi): size{vi.size}, ptr{new int[size]} {
 38     for(auto i = 0; i < size; ++i)
 39         ptr[i] = vi.ptr[i];
 40 }
 41 
 42 vectorInt::~vectorInt() {
 43     delete [] ptr;
 44 }
 45 
 46 const int& vectorInt::at(int index) const {
 47     assert(index >= 0 && index < size);
 48 
 49     return ptr[index];
 50 }
 51 
 52 int& vectorInt::at(int index) {
 53     assert(index >= 0 && index < size);
 54 
 55     return ptr[index];
 56 }
 57 
 58 vectorInt& vectorInt::assign(const vectorInt &v) {  
 59     delete[] ptr;       // 释放对象中ptr原来指向的资源
 60 
 61     size = v.size;
 62     ptr = new int[size];
 63 
 64     for(int i = 0; i < size; ++i)
 65         ptr[i] = v.ptr[i];
 66 
 67     return *this;
 68 }
 69 
 70 int vectorInt::get_size() const {
 71     return size;
 72 }
 73 //task3.cpp
 74 #include "vectorInt.hpp"
 75 #include <iostream>
 76 
 77 using std::cin;
 78 using std::cout;
 79 
 80 void output(const vectorInt &vi) {
 81     for(auto i = 0; i < vi.get_size(); ++i)
 82         cout << vi.at(i) << ", ";
 83     cout << "\b\b \n";
 84 }
 85 
 86 
 87 void test1() {
 88     int n;
 89     cout << "Enter n: ";
 90     cin >> n;
 91 
 92     vectorInt x1(n);
 93     for(auto i = 0; i < n; ++i)
 94         x1.at(i) = i*i;
 95     cout << "x1: ";  output(x1);
 96 
 97     vectorInt x2(n, 42);
 98     vectorInt x3(x2);
 99     x2.at(0) = -999;
100     cout << "x2: ";  output(x2);
101     cout << "x3: ";  output(x3);
102 }
103 
104 void test2() {
105     const vectorInt  x(5, 42);
106     vectorInt y(10, 0);
107 
108     cout << "y: ";  output(y);
109     y.assign(x);
110     cout << "y: ";  output(y);
111     
112     cout << "x.at(0) = " << x.at(0) << endl;
113     cout << "y.at(0) = " << y.at(0) << endl;
114 }
115 
116 int main() {
117     cout << "测试1: \n";
118     test1();
119 
120     cout << "\n测试2: \n";
121     test2();
122 }
View Code

 

(2)运行结果

 

(3)

问题一:

深复制;

问题二:

int & at(int index);中返回值类型改成int将不能正确运行const int & at(int index) const;中返回值类型改成int将可以正确运行;这是因为当返回值为int时,函数返回的是一个值的副本而不是引用,不能通过返回值来修改对象中的元素;将line18前面的const去掉对于测试代码没有安全隐患;

问题三:

将返回值改为vectorInt类型,返回的是整个数组的副本,会增加内存开销;

 

实验任务四

(1)代码部分

  1 //Matrix.hpp
  2 #pragma once
  3 
  4 #include <iostream>
  5 #include <cassert>
  6 
  7 using std::cout;
  8 using std::endl;
  9 
 10 // 类Matrix的声明
 11 class Matrix {
 12 public:
 13     Matrix(int n, int m);           // 构造函数,构造一个n*m的矩阵, 初始值为value
 14     Matrix(int n);                  // 构造函数,构造一个n*n的矩阵, 初始值为value
 15     Matrix(const Matrix &x);        // 复制构造函数, 使用已有的矩阵X构造
 16     ~Matrix();
 17 
 18     void set(const double *pvalue);         // 用pvalue指向的连续内存块数据按行为矩阵赋值
 19     void clear();                           // 把矩阵对象的值置0
 20     
 21     const double& at(int i, int j) const;   // 返回矩阵对象索引(i,j)的元素const引用
 22     double& at(int i, int j);               // 返回矩阵对象索引(i,j)的元素引用
 23     
 24     int get_lines() const;                  // 返回矩阵对象行数
 25     int get_cols() const;                   // 返回矩阵对象列数
 26 
 27     void display() const;                    // 按行显示矩阵对象元素值
 28 
 29 private:
 30     int lines;      // 矩阵对象内元素行数
 31     int cols;       // 矩阵对象内元素列数
 32     double *ptr;
 33 };
 34 
 35 // 类Matrix的实现:待补足
 36 // xxx
 37 Matrix::Matrix(int n,int m):lines{n},cols{m},ptr{new double[n*m]}{};
 38 Matrix::Matrix(int n):lines{n},cols{n},ptr{new double[n*n]}{};
 39 Matrix::Matrix(const Matrix &x):lines{x.lines},cols{x.cols},ptr{new double[lines*cols]}{
 40     for(int i=0;i<lines;i++)
 41     for(int j=0;j<cols;j++){
 42         ptr[i*cols+j]=x.ptr[i*cols+j];
 43     }
 44 }
 45 Matrix::~Matrix(){
 46     delete [] ptr;
 47 }
 48 void Matrix::set(const double *pvalue){
 49     for(int i=0;i<lines;i++)
 50     for(int j=0;j<cols;j++){
 51         ptr[i*cols+j]=*pvalue;
 52         pvalue++;
 53     }
 54 }
 55 void Matrix::clear(){
 56     for(int i=0;i<lines;i++)
 57     for(int j=0;j<cols;j++){
 58         ptr[i*cols+j]=0;
 59     }
 60 }
 61 const double& Matrix::at(int i, int j) const{
 62     return ptr[i*cols+j];
 63 }
 64 double& Matrix::at(int i, int j){
 65     return ptr[i*cols+j];
 66 }
 67 int Matrix::get_lines() const{
 68     return lines;
 69 }
 70 int Matrix::get_cols() const{
 71     return cols;
 72 }
 73 void Matrix::display() const{
 74     for(int i=0;i<lines;i++){
 75         for(int j=0;j<cols-1;j++){
 76             cout<<ptr[i*cols+j]<<',';
 77         }
 78         cout<<ptr[i*cols+cols-1]<<endl;
 79     }
 80 }
 81 
 82 //task4.cpp
 83 #include "matrix.hpp"
 84 #include <iostream>
 85 #include <cassert>
 86 
 87 using std::cin;
 88 using std::cout;
 89 using std::endl;
 90 
 91 
 92 const int N = 1000;
 93 
 94 // 输出矩阵对象索引为index所在行的所有元素
 95 void output(const Matrix &m, int index) {
 96     assert(index >= 0 && index < m.get_lines());
 97 
 98     for(auto j = 0; j < m.get_cols(); ++j)
 99         cout << m.at(index, j) << ", ";
100     cout << "\b\b \n";
101 }
102 
103 
104 void test1() {
105     double x[1000] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
106 
107     int n, m;
108     cout << "Enter n and m: ";
109     cin >> n >> m;
110 
111     Matrix m1(n, m);    // 创建矩阵对象m1, 大小n×m
112     m1.set(x);          // 用一维数组x的值按行为矩阵m1赋值
113 
114     Matrix m2(m, n);    // 创建矩阵对象m1, 大小m×n
115     m2.set(x);          // 用一维数组x的值按行为矩阵m1赋值
116 
117     Matrix m3(2);       // 创建一个2×2矩阵对象
118     m3.set(x);          // 用一维数组x的值按行为矩阵m4赋值
119 
120     cout << "矩阵对象m1: \n";   m1.display();  cout << endl;
121     cout << "矩阵对象m2: \n";   m2.display();  cout << endl;
122     cout << "矩阵对象m3: \n";   m3.display();  cout << endl;
123 }
124 
125 void test2() {
126     Matrix m1(2, 3);
127     m1.clear();
128     
129     const Matrix m2(m1);
130     m1.at(0, 0) = -999;
131 
132     cout << "m1.at(0, 0) = " << m1.at(0, 0) << endl;
133     cout << "m2.at(0, 0) = " << m2.at(0, 0) << endl;
134     cout << "矩阵对象m1第0行: "; output(m1, 0);
135     cout << "矩阵对象m2第0行: "; output(m2, 0);
136 }
137 
138 int main() {
139     cout << "测试1: \n";
140     test1();
141 
142     cout << "测试2: \n";
143     test2();
144 }
View Code

 

(2)运行结果

 

实验任务五

(1)代码部分

  1 #pragma once
  2 
  3 #include <iostream>
  4 #include <vector>
  5 #include <string>
  6 #include<cstring>
  7 
  8 using std::cin;
  9 using std::cout;
 10 using std::endl;
 11 using std::vector;
 12 using std::string;
 13 
 14 class User{
 15 public:
 16     User(string s1,string s2="123456",string s3="");
 17     void set_email();
 18     void change_password();
 19     void display() const;
 20 private:
 21     string name;
 22     string password;
 23     string email;
 24 };
 25 
 26 User::User(string s1,string s2,string s3):name{s1},password{s2},email{s3}{};
 27 void User::set_email(){
 28     int n;
 29     string temp;
 30     cout<<"Enter email address:";
 31     cin>>temp;
 32     while((n=temp.find('@'))!=string::npos){
 33         cout<<"illegal email.Please re-enter email:";
 34         cin>>temp;
 35         cout<<endl;
 36     }
 37     email=temp;
 38     cout<<endl;
 39     cout<<"email is set successfully..."<<endl;
 40 }
 41 void User::change_password(){
 42     string old,newpass;
 43     cout<<"Enter old password:";
 44     cin>>old;
 45     cout<<endl;
 46     for(int i=1;i<3;i++){
 47         if(old==password){
 48             cout<<"Enter new password:";
 49             cin>>newpass;
 50             cout<<endl;
 51             password=newpass;
 52             cout<<"new password is set successfully..."<<endl;
 53             return;
 54         }
 55         else{
 56             cout<<"password input error.Please re-enter again:";
 57             cin>>old;
 58             cout<<endl;
 59         }
 60     }
 61     cout<<"password input error.Please try after a while."<<endl;
 62 }
 63 void User::display() const{
 64     cout<<"name: "<<name<<endl;
 65     cout<<"pass: "<<string(password.size(),'*')<<endl;
 66     cout<<"email: "<<email<<endl;
 67 }
 68 
 69 #include "user.hpp"
 70 #include <iostream>
 71 #include <vector>
 72 #include <string>
 73 
 74 using std::cin;
 75 using std::cout;
 76 using std::endl;
 77 using std::vector;
 78 using std::string;
 79 
 80 void test() {
 81     vector<User> user_lst;
 82 
 83     User u1("Alice", "2024113", "Alice@hotmail.com");
 84     user_lst.push_back(u1);
 85     cout << endl;
 86 
 87     User u2("Bob");
 88     u2.set_email();
 89     u2.change_password();
 90     user_lst.push_back(u2);
 91     cout << endl;
 92 
 93     User u3("Hellen");
 94     u3.set_email();
 95     u3.change_password();
 96     user_lst.push_back(u3);
 97     cout << endl;
 98 
 99     cout << "There are " << user_lst.size() << " users. they are: " << endl;
100     for(auto &i: user_lst) {
101         i.display();
102         cout << endl;
103     }
104 }
105 
106 int main() {
107     test();
108 }
View Code

 

(2)运行结果

 

实验任务六

(1)代码部分

  1 //date.h
  2 #ifndef __DATE_H__
  3 #define __DATE_H__
  4 class Date {
  5 private:
  6     int year;        
  7     int month;        
  8     int day;        
  9     int totalDays;    
 10 public:
 11     Date(int year, int month, int day);    
 12     int getYear() const { return year; }
 13     int getMonth() const { return month; }
 14     int getDay() const { return day; }
 15     int getMaxDay() const;        
 16     bool isLeapYear() const {    
 17         return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
 18     }
 19     void show() const;            
 20    
 21     int distance(const Date& date) const {
 22         return totalDays - date.totalDays;
 23     }
 24 };
 25 #endif //__DATE_H__
 26 
 27 //date.cpp
 28 #include "date.h"
 29 #include <iostream>
 30 #include <cstdlib>
 31 using namespace std;
 32 namespace {    
 33     const int DAYS_BEFORE_MONTH[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
 34 }
 35 Date::Date(int year, int month, int day) : year(year), month(month), day(day) {
 36     if (day <= 0 || day > getMaxDay()) {
 37         cout << "Invalid date: ";
 38         show();
 39         cout << endl;
 40         exit(1);
 41     }
 42     int years = year - 1;
 43     totalDays = years * 365 + years / 4 - years / 100 + years / 400
 44         + DAYS_BEFORE_MONTH[month - 1] + day;
 45     if (isLeapYear() && month > 2) totalDays++;
 46 }
 47 int Date::getMaxDay() const {
 48     if (isLeapYear() && month == 2)
 49         return 29;
 50     else
 51         return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1];
 52 }
 53 void Date::show() const {
 54     cout << getYear() << "-" << getMonth() << "-" << getDay();
 55 }
 56 
 57 //account.h
 58 #ifndef __ACCOUNT_H__
 59 #define __ACCOUNT_H__
 60 #include "date.h"
 61 #include <string>
 62 class SavingsAccount { 
 63 private:
 64     std::string id;        
 65     double balance;        
 66     double rate;        
 67     Date lastDate;        
 68     double accumulation;    
 69     static double total;    
 70    
 71     void record(const Date& date, double amount, const std::string& desc);
 72     
 73     void error(const std::string& msg) const;
 74     
 75     double accumulate(const Date& date) const {
 76         return accumulation + balance * date.distance(lastDate);
 77     }
 78 public:
 79   
 80     SavingsAccount(const Date& date, const std::string& id, double rate);
 81     const std::string& getId() const { return id; }
 82     double getBalance() const { return balance; }
 83     double getRate() const { return rate; }
 84     static double getTotal() { return total; }
 85   
 86     void deposit(const Date& date, double amount, const std::string& desc);
 87    
 88     void withdraw(const Date& date, double amount, const std::string& desc);
 89   
 90     void settle(const Date& date);
 91   
 92     void show() const;
 93 };
 94 #endif //__ACCOUNT_H__
 95 
 96 
 97 //account.cpp
 98 #include "account.h"
 99 #include <cmath>
100 #include <iostream>
101 using namespace std;
102 double SavingsAccount::total = 0;
103 SavingsAccount::SavingsAccount(const Date& date, const string& id, double rate)
104     : id(id), balance(0), rate(rate), lastDate(date), accumulation(0) {
105     date.show();
106     cout << "\t#" << id << " created" << endl;
107 }
108 void SavingsAccount::record(const Date& date, double amount, const string& desc) {
109     accumulation = accumulate(date);
110     lastDate = date;
111     amount = floor(amount * 100 + 0.5) / 100;
112     balance += amount;
113     total += amount;
114     date.show();
115     cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
116 }
117 void SavingsAccount::error(const string& msg) const {
118     cout << "Error(#" << id << "): " << msg << endl;
119 }
120 void SavingsAccount::deposit(const Date& date, double amount, const string& desc) {
121     record(date, amount, desc);
122 }
123 void SavingsAccount::withdraw(const Date& date, double amount, const string& desc) {
124     if (amount > getBalance())
125         error("not enough money");
126     else
127         record(date, -amount, desc);
128 }
129 void SavingsAccount::settle(const Date& date) {
130     double interest = accumulate(date) * rate / date.distance(Date(date.getYear() - 1, 1, 1));
131     if (interest != 0)
132         record(date, interest, "interest");
133     accumulation = 0;
134 }
135 void SavingsAccount::show() const {
136     cout << id << "\tBalance: " << balance;
137 }
138 
139 //main.cpp
140 #include "account.h"
141 #include <iostream>
142 using namespace std;
143 int main() {
144     Date date(2008, 11, 1);
145     SavingsAccount accounts[] = {
146             SavingsAccount(date, "03755217", 0.015),
147             SavingsAccount(date, "02342342", 0.015)
148     };
149     const int n = sizeof(accounts) / sizeof(SavingsAccount); 
150 
151     accounts[0].deposit(Date(2008, 11, 5), 5000, "salary");
152     accounts[1].deposit(Date(2008, 11, 25), 10000, "sell stock 0323");
153 
154     accounts[0].deposit(Date(2008, 12, 5), 5500, "salary");
155     accounts[1].withdraw(Date(2008, 12, 20), 4000, "buy a laptop");
156 
157     cout << endl;
158     for (int i = 0; i < n; i++) {
159         accounts[i].settle(Date(2009, 1, 1));
160         accounts[i].show();
161         cout << endl;
162     }
163     cout << "Total: " << SavingsAccount::getTotal() << endl;
164     return 0;
165 }
View Code

 

(2)运行结果

 

posted @ 2024-11-08 15:26  刘晔yyy  阅读(2)  评论(0编辑  收藏  举报