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

 

1.两个类window和button 两个标准库类string和vector。

2.没必要。剩下的函数执行时不会改变对象值。

3.定义一个对象s,其长度为40且都是“*”。

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

1.定义一个长度为5的一维数组,其元素均为42;定义一个和v1相同的数组v2;将v1中第一个元素修改为-999。

2.定义一个二维数组v1,第一行为123,第二行为4567;定义一个和v1相同且值不能改变的数组v2;在v1第一行末尾插入一个值-999。

3.定义一个数组t1,其元素为v1的第一行元素,输出t1的最后一个元素;定义一个不能改变的数组v2,其值为v2的第一行元素,输出t2的最后一个元素。

4.深复制;是

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

1.深复制。

2.不能。存在安全隐患,int&表示新变量与其共享内存,若去掉const,后续新变量值改变时会一起改变原先变量的值。

3.可以。这段代码目的是为了将v的内容赋值给当前对象,若改成vectorint,就是调用复制构造函数生成一个新对象,对结果没有影响。

  1 #pragma once
  2 
  3 #include <iostream>
  4 #include <cassert>
  5 
  6 using std::cout;
  7 using std::endl;
  8 
  9 // 类Matrix的声明
 10 class Matrix {
 11 public:
 12     Matrix(int n, int m);           // 构造函数,构造一个n*m的矩阵, 初始值为value
 13     Matrix(int n);                  // 构造函数,构造一个n*n的矩阵, 初始值为value
 14     Matrix(const Matrix &x);        // 复制构造函数, 使用已有的矩阵X构造
 15     ~Matrix();
 16 
 17     void set(const double *pvalue);         // 用pvalue指向的连续内存块数据按行为矩阵赋值
 18     void clear();                           // 把矩阵对象的值置0
 19     
 20     const double& at(int i, int j) const;   // 返回矩阵对象索引(i,j)的元素const引用
 21     double& at(int i, int j);               // 返回矩阵对象索引(i,j)的元素引用
 22     
 23     int get_lines() const;                  // 返回矩阵对象行数
 24     int get_cols() const;                   // 返回矩阵对象列数
 25 
 26     void display() const;                    // 按行显示矩阵对象元素值
 27 
 28 private:
 29     int lines;      // 矩阵对象内元素行数
 30     int cols;       // 矩阵对象内元素列数
 31     double *ptr;
 32 };
 33 
 34 // 类Matrix的实现:待补足
 35 // xxx
 36 
 37 
 38 
 39 
 40 
 41 #include "matrix.hpp"
 42 #include <iostream>
 43 #include <cassert>
 44 
 45 using namespace std;
 46 
 47 // 构造函数:使用行数 n 和列数 m 初始化矩阵
 48 Matrix::Matrix(int n, int m) : lines(n), cols(m) {
 49     assert(n > 0 && m > 0);
 50     ptr = new double[n * m]();  // 动态分配内存并初始化为 0
 51 }
 52 
 53 // 构造函数:初始化为一个 n x n 的方阵
 54 Matrix::Matrix(int n) : lines(n), cols(n) {
 55     assert(n > 0);
 56     ptr = new double[n * n]();  // 动态分配内存并初始化为 0
 57 }
 58 
 59 // 拷贝构造函数:进行深复制
 60 Matrix::Matrix(const Matrix& x) : lines(x.lines), cols(x.cols) {
 61     ptr = new double[lines * cols];
 62     for (int i = 0; i < lines * cols; ++i) {
 63         ptr[i] = x.ptr[i];
 64     }
 65 }
 66 
 67 // 析构函数:释放动态分配的内存
 68 Matrix::~Matrix() {
 69     delete[] ptr;
 70 }
 71 
 72 // 使用给定的数组 pvalue 初始化矩阵内容
 73 void Matrix::set(const double* pvalue) {
 74     for (int i = 0; i < lines * cols; ++i) {
 75         ptr[i] = pvalue[i];
 76     }
 77 }
 78 
 79 // 将矩阵所有元素设为 0
 80 void Matrix::clear() {
 81     for (int i = 0; i < lines * cols; ++i) {
 82         ptr[i] = 0;
 83     }
 84 }
 85 
 86 // 常量版本的 at 函数:获取矩阵中的元素,不能修改
 87 const double& Matrix::at(int i, int j) const {
 88     assert(i >= 0 && i < lines && j >= 0 && j < cols);
 89     return ptr[i * cols + j];
 90 }
 91 
 92 // 非常量版本的 at 函数:获取矩阵中的元素,可修改
 93 double& Matrix::at(int i, int j) {
 94     assert(i >= 0 && i < lines && j >= 0 && j < cols);
 95     return ptr[i * cols + j];
 96 }
 97 
 98 // 获取矩阵的行数
 99 int Matrix::get_lines() const {
100     return lines;
101 }
102 
103 // 获取矩阵的列数
104 int Matrix::get_cols() const {
105     return cols;
106 }
107 
108 // 输出矩阵的内容
109 void Matrix::display() const {
110     for (int i = 0; i < lines; ++i) {
111         for (int j = 0; j < cols; ++j) {
112             cout << at(i, j) << " ";
113         }
114         cout << endl;
115     }
116 }
117 
118 
119 
120 
121 #include "matrix.hpp"
122 #include <iostream>
123 #include <cassert>
124 
125 using std::cin;
126 using std::cout;
127 using std::endl;
128 
129 
130 const int N = 1000;
131 
132 // 输出矩阵对象索引为index所在行的所有元素
133 void output(const Matrix &m, int index) {
134     assert(index >= 0 && index < m.get_lines());
135 
136     for(auto j = 0; j < m.get_cols(); ++j)
137         cout << m.at(index, j) << ", ";
138     cout << "\b\b \n";
139 }
140 
141 
142 void test1() {
143     double x[1000] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
144 
145     int n, m;
146     cout << "Enter n and m: ";
147     cin >> n >> m;
148 
149     Matrix m1(n, m);    // 创建矩阵对象m1, 大小n×m
150     m1.set(x);          // 用一维数组x的值按行为矩阵m1赋值
151 
152     Matrix m2(m, n);    // 创建矩阵对象m1, 大小m×n
153     m2.set(x);          // 用一维数组x的值按行为矩阵m1赋值
154 
155     Matrix m3(2);       // 创建一个2×2矩阵对象
156     m3.set(x);          // 用一维数组x的值按行为矩阵m4赋值
157 
158     cout << "矩阵对象m1: \n";   m1.display();  cout << endl;
159     cout << "矩阵对象m2: \n";   m2.display();  cout << endl;
160     cout << "矩阵对象m3: \n";   m3.display();  cout << endl;
161 }
162 
163 void test2() {
164     Matrix m1(2, 3);
165     m1.clear();
166     
167     const Matrix m2(m1);
168     m1.at(0, 0) = -999;
169 
170     cout << "m1.at(0, 0) = " << m1.at(0, 0) << endl;
171     cout << "m2.at(0, 0) = " << m2.at(0, 0) << endl;
172     cout << "矩阵对象m1第0行: "; output(m1, 0);
173     cout << "矩阵对象m2第0行: "; output(m2, 0);
174 }
175 
176 int main() {
177     cout << "测试1: \n";
178     test1();
179 
180     cout << "测试2: \n";
181     test2();
182 }
task4

  1 #pragma once
  2 #include <iostream>
  3 #include <string>
  4 
  5 using namespace std;
  6 
  7 class User {
  8 private:
  9     string name;       // 用户名
 10     string password;   // 密码
 11     string email;      // 邮箱
 12 
 13 public:
 14     // 构造函数:允许仅使用用户名初始化
 15     User(const string& n, const string& p = "", const string& e = "")
 16         : name(n), password(p), email(e) {}
 17 
 18     // 设置邮箱
 19     void set_email() {
 20         string input_email;
 21         while (true) {
 22             cout << "Enter email address: ";
 23             cin >> input_email;
 24 
 25             // 简单检查邮箱是否包含 '@' 和 '.' 符号
 26             if (input_email.find('@') != string::npos && input_email.find('.') != string::npos) {
 27                 email = input_email;
 28                 cout << "Email is set successfully..." << endl;
 29                 break;
 30             } else {
 31                 cout << "Illegal email. Please re-enter email: ";
 32             }
 33         }
 34     }
 35 
 36     // 修改密码
 37     void change_password() {
 38         string old_password, new_password, confirm_password;
 39 
 40         cout << "Enter old password: ";
 41         cin >> old_password;
 42 
 43         // 检查旧密码是否正确
 44         if (old_password == password) {
 45             while (true) {
 46                 cout << "Enter new password: ";
 47                 cin >> new_password;
 48 
 49                 cout << "Please re-enter again: ";
 50                 cin >> confirm_password;
 51 
 52                 // 检查两次输入的密码是否一致
 53                 if (new_password == confirm_password) {
 54                     password = new_password;
 55                     cout << "New password is set successfully..." << endl;
 56                     break;
 57                 } else {
 58                     cout << "Password input error. Please re-enter again." << endl;
 59                 }
 60             }
 61         } else {
 62             cout << "Password input error. Please try after a while." << endl;
 63         }
 64     }
 65 
 66     // 显示用户信息
 67     void display() const {
 68         cout << "Name: " << name << endl;
 69         cout << "Pass: " << (password.empty() ? "******" : password) << endl;
 70         cout << "Email: " << (email.empty() ? "******" : email) << endl;
 71     }
 72 };
 73 
 74 
 75 
 76 
 77 
 78 #include "user.hpp"
 79 #include <iostream>
 80 #include <vector>
 81 #include <string>
 82 
 83 using std::cin;
 84 using std::cout;
 85 using std::endl;
 86 using std::vector;
 87 using std::string;
 88 
 89 void test() {
 90     vector<User> user_lst;
 91 
 92     User u1("Alice", "2024113", "Alice@hotmail.com");
 93     user_lst.push_back(u1);
 94     cout << endl;
 95 
 96     User u2("Bob","123456");
 97     u2.set_email();
 98     u2.change_password();
 99     user_lst.push_back(u2);
100     cout << endl;
101 
102     User u3("Hellen");
103     u3.set_email();
104     u3.change_password();
105     user_lst.push_back(u3);
106     cout << endl;
107 
108     cout << "There are " << user_lst.size() << " users. they are: " << endl;
109     for(auto &i: user_lst) {
110         i.display();
111         cout << endl;
112     }
113 }
114 
115 int main() {
116     test();
117 }
task5

 

 

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