实验3
1 #pragma once 2 #include "button.hpp" 3 #include<vector> 4 #include<iostream> 5 6 using std::vector; 7 using std::cout; 8 using std::endl; 9 10 //窗口类 11 class window { 12 public: 13 window(const string& win_title); 14 void display()const; 15 void close(); 16 void add_button(const string& label); 17 18 private: 19 string title; 20 vector<Button> buttons; 21 }; 22 23 window::window(const string& win_title) :title{ win_title } { 24 buttons.push_back(Button("close")); 25 } 26 27 inline void window::display()const { 28 string s(40, '*'); 29 cout << s << endl; 30 cout << "window title: " << title << endl; 31 cout << "It has " << buttons.size() << "buttons: " << endl; 32 for (const auto& i : buttons) 33 cout << i.get_label() << " button" << endl; 34 cout << s << endl; 35 } 36 37 void window::close() { 38 cout << "close window '" << title << " ' " << endl; 39 buttons.at(0).click(); 40 } 41 42 void window::add_button(const string& label) { 43 buttons.push_back(Button(label)); 44 } 45 46 47 //任务1 48 #include "window.hpp" 49 #include<iostream> 50 using std::cout; 51 using std::cin; 52 53 void test() { 54 window w1{ "new window" }; 55 w1.add_button("maximize"); 56 w1.display(); 57 w1.close(); 58 } 59 60 int main() { 61 cout << "用组合类模拟简单GUI:\n"; 62 test(); 63 } 64 //问题1:自定义了2个类:按钮类和窗口类。使用到了标准库的3个类:<iostream><string><vector>。按钮类和<iostream><vector>,窗口类和<iostream><string>存在组合关系 65 //问题2:都不合适。没加const的成员函数都是需要更改数据的,const明显与功能不符;没加inline的成员函数都是需要反复调用的,inline反而会增大可执行体的体积 66 //问题3:打出一行长度为40的*字符串,起分隔作用
1 #pragma once 2 #include<iostream> 3 #include<string> 4 using std::string; 5 using std::cout; 6 //按钮类 7 class Button { 8 public: 9 Button(const string& text); 10 string get_label()const; 11 void click(); 12 13 private: 14 string label; 15 }; 16 17 Button::Button(const string& text) :label{ text } { 18 } 19 inline string Button::get_label()const { 20 return label; 21 } 22 23 void Button::click() { 24 cout << "Button'" << label << "'clicked\n"; 25 }
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 void output1(const vector<int>& v) { 5 for (auto& i : v) 6 cout << i << ", "; 7 cout << "\b\b \n"; 8 } 9 void output2(const vector<vector<int>> v) { 10 for (auto& i : v) { 11 for (auto& j : i) { 12 cout << j << ", "; 13 } 14 cout << "\b\b \n"; 15 } 16 } 17 18 void test1() { 19 vector<int>v1(5, 42); 20 const vector<int> v2(v1); 21 v1.at(0) = -999; 22 cout << "v1: "; output1(v1); 23 cout << "v2: "; output1(v2); 24 cout << "v1.at(0)=" << v1.at(0) << endl; 25 cout << "v2.at(0)=" << v2.at(0) << endl; 26 } 27 28 void test2() { 29 vector<vector<int>>v1{ {1,2,3},{4,5,6,7} }; 30 const vector<vector<int>> v2(v1); 31 v1.at(0).push_back(-999); 32 cout << "v1: \n"; output2(v1); 33 cout << "v2: \n"; output2(v2); 34 35 vector<int>t1 = v1.at(0); 36 cout << t1.at(t1.size() - 1) << endl; 37 const vector<int> t2 = v2.at(0); 38 cout << t2.at(t2.size() - 1) << endl; 39 40 } 41 42 int main() { 43 cout << "测试1:\n"; 44 test1(); 45 cout << "\n测试2:\n"; 46 test2(); 47 } 48 //问题1:21行:定义一个长度为5值为42的整形vector对象;22行:将v1复制构造一个vector对象v2;23行:更改v1中第一个元素的值 49 //问题2:32行:定义一个整型二维vector对象v1,并赋值;33行:将v1复制构造给一个vector对象v2;23行:用at成员函数访问二维vector的第一个元素,并向末尾添加-999 50 //问题3:分别从一个可修改的二维向量v1和一个常量二维向量v2中提取并输出最后一个元素 51 //问题4:深复制。应至少提供一个const成员函数作为接口,否则用户无法在代码的const vector上调用该方法
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 void test1() { 14 int n; 15 cout << "Enter n: "; 16 cin >> n; 17 18 vectorInt x1(n); 19 for (auto i = 0; i < n; i++) 20 x1.at(i) = i * i; 21 cout << "x1: "; 22 23 output(x1); 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 cout << "y: "; output(y); 35 y.assign(x); 36 cout << "y: "; output(y); 37 38 cout << "x.at(0)= " << x.at(0) << endl; 39 cout << "x.at(0)= " << y.at(0) << endl; 40 41 } 42 int main() { 43 cout << "测试1:\n"; 44 test1(); 45 cout << "测试2: \n"; 46 test2(); 47 } 48 //问题1:深复制,因为释放了原有资源并重新分配了新内存 49 //问题2:不能,&删掉就是int类型,不能更改数值;有安全隐患,可能会出现左边的返回值 50 //问题3:可以,但是有不必要的复制导致的内存开销 51 //附加:注意对vectorInt的使用,不要造成额外的性能消耗
1 //vectorInt.hpp 2 #pragma once 3 #include <iostream> 4 #include <cassert> 5 using std::cout; 6 using std::endl; 7 // 动态int数组对象类 8 class vectorInt { 9 public: 10 vectorInt(int n); 11 vectorInt(int n, int value); 12 vectorInt(const vectorInt& vi); 13 ~vectorInt(); 14 15 16 17 18 int& at(int index); 19 const int& at(int index) const; 20 vectorInt& assign(const vectorInt& v); 21 int get_size() const; 22 private: 23 int size; 24 int* ptr; // ptr指向包含size个int的数组 25 }; 26 vectorInt::vectorInt(int n) : size{ n }, ptr{ new int[size] } { 27 } 28 vectorInt::vectorInt(int n, int value) : size{ n }, ptr{ new int[size] } { 29 for (auto i = 0; i < size; ++i) 30 ptr[i] = value; 31 } 32 vectorInt::vectorInt(const vectorInt& vi) : size{ vi.size }, ptr{ new int[size] } 33 { 34 for (auto i = 0; i < size; ++i) 35 ptr[i] = vi.ptr[i]; 36 } 37 vectorInt::~vectorInt() { 38 delete[] ptr; 39 } 40 const int& vectorInt::at(int index) const { 41 assert(index >= 0 && index < size); 42 return ptr[index]; 43 } 44 int& vectorInt::at(int index) { 45 assert(index >= 0 && index < size); 46 return ptr[index]; 47 } 48 vectorInt& vectorInt::assign(const vectorInt& v) { 49 delete[] ptr; // 释放对象中ptr原来指向的资源 50 size = v.size; 51 ptr = new int[size]; 52 for (int i = 0; i < size; ++i) 53 ptr[i] = v.ptr[i]; 54 return *this; 55 } 56 int vectorInt::get_size() const { 57 return size; 58 } 59 int vectorInt::get_size() const { 60 return size; 61 }
1 //Matrix.hpp 2 #pragma once 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); 13 Matrix(int n); 14 Matrix(const Matrix& x); 15 ~Matrix(); 16 17 void set(const double* pvalue); 18 19 void clear(); 20 21 const double& at(int i, int j)const; 22 double& at(int i, int j); 23 24 double& at(int i, int j); 25 26 int get_lines()const; 27 int get_cols()const; 28 29 void display()const; 30 private: 31 int lines; 32 int cols; 33 double* ptr; 34 }; 35 36 Matrix::Matrix(int n, int m) :lines(n), cols(m) { 37 ptr = new double[n * m]; 38 clear(); 39 } 40 41 Matrix::Matrix(int n) :Matrix(n, n) { 42 ptr = new double[n * n]; 43 clear(); 44 } 45 46 Matrix::Matrix(const Matrix& x) :lines(x.lines), cols(x.cols) { 47 ptr = new double[lines * cols]; 48 for (int i = 0; i < lines * cols; i++) 49 ptr[i] = x.ptr[i]; 50 } 51 52 Matrix::~Matrix() { 53 delete[]ptr; 54 } 55 56 void Matrix::set(const double* pvalue) { 57 for (int i = 0; i < lines * cols; i++) 58 ptr[i] = 0; 59 } 60 61 void Matrix::clear() { 62 for (int i = 0; i < lines * cols; i++) 63 ptr[i] = 0; 64 } 65 66 const double& Matrix::at(int i, int j)const { 67 assert(i >= 0 && i < lines && j >= 0 && j < cols); 68 return*(ptr + cols * i + j); 69 } 70 71 double& Matrix::at(int i, int j){ 72 assert(i >= 0 && i < lines && j >= 0 && j < cols); 73 return*(ptr + cols * i + j); 74 } 75 76 int Matrix::get_lines() const{ 77 return lines; 78 } 79 80 int Matrix::get_cols()const { 81 return cols; 82 } 83 84 void Matrix::display()const{ 85 for (int i = 0; i <lines; i++) 86 { 87 for (int j = 0; j < cols; j++) 88 { 89 cout << ptr[i * cols + j] << " "; 90 } 91 cout << endl; 92 } 93 }
1 #include "matrix.hpp" 2 #include<iostream> 3 #include<cassert> 4 5 using std::sin; 6 using std::cout; 7 using std::endl; 8 9 const int N = 1000; 10 11 12 13 void output(const Matrix& m, int index) { 14 assert(index >= 0 && index < m.get_lines()); 15 16 for (auto j = 0; j < m.get_cols(); ++j) 17 cout << m.at(index, j) << ","; 18 cout << "\b\b \n"; 19 } 20 21 22 void test1() { 23 double x[1000] = { 1,2,3,4,5,6,7,8,9 }; 24 25 int n, m; 26 cout << "Enter n and m: "; 27 cin >> n >> m; 28 29 Matrix m1(n, m); 30 m1.set(x); 31 32 Matrix m2(n, m); 33 m2.set(x); 34 35 Matrix m3(2); 36 m3.set(x); 37 38 cout << "矩形对象m1:\n"; m1.display(); cout << endl; 39 cout << "矩形对象m2:\n"; m2.display(); cout << endl; 40 cout << "矩形对象m3:\n"; m3.display(); cout << endl; 41 } 42 43 void test2() { 44 Matrix m1(2, 3); 45 m1.clear(); 46 47 const Matrix m2(m1); 48 m1.at(0, 0) = -999; 49 50 cout << "m1.at(0,0)= " << m1.at(0, 0) << endl; 51 cout << "m2.at(0,0)= " << m2.at(0, 0) << endl; 52 cout << "矩阵对象m1第0行:"; output(m1, 0); 53 cout << "矩阵对象m2第0行:"; output(m2, 0); 54 } 55 56 int main() { 57 cout << "测试1:\n"; 58 test1(); 59 cout << "测试2:\n"; 60 test2(); 61 }
1 //user.hpp 2 #pragma once 3 #include<iostream> 4 #include<string> 5 using std::string; 6 using std::cout; 7 using namespace std; 8 9 class User { 10 private: 11 string name, password, email; 12 13 public: 14 User(string name, string password = " ", string email = " ") : 15 name(name), password(password), email(email) {} 16 User(); 17 void set_email(); 18 void change_password(); 19 void display(); 20 }; 21 22 User::User(string name, string password = " ", string email = " ") : 23 name(name), password(password), email(email){} 24 25 User::User(){} 26 27 User::set_email() { 28 while (true) 29 cout << "Enter your email:"; 30 string newone; 31 cin >> newone; 32 while (newone.find('@') == string::npos) { 33 cout << "Illegal email.Please re-enter email:"; 34 cin >> newone; 35 } 36 email = newone; 37 cout << "email is set successfully..." << endl; 38 } 39 40 User::change_password() { 41 cout << "Enter old password:"; 42 string newone; 43 int n = 2; 44 cin >> newone; 45 while (n--) { 46 47 if (newone == password) 48 { 49 50 cout << "Enter new password:"; 51 cin >> newone; 52 password = newone; 53 cout << "new password is set successfully..." << endl << endl; 54 break; 55 } 56 57 cout << "password input error.Please re-enter again:"; 58 cin >> newone; 59 } 60 if (n == -1) { 61 cout << "password input error. Please try after a while." << endl; 62 63 } 64 } 65 66 User::display() 67 { 68 std::cout << "Username: " << name << std::endl; 69 std::cout << "Password: " << std::string(password.length(), '*') 70 << std::endl; 71 std::cout << "Email: " << email << std::endl; 72 }
1 #include "user.hpp" 2 #include<iostream> 3 #include<vector> 4 #include<string> 5 6 using std::cin; 7 using std::cout; 8 using std::endl; 9 using std::vector; 10 using std::string; 11 12 void test() { 13 vector<User> user_1st; 14 15 User u1("Alice", "2024113","Alice@hotmail.com") 16 user_1st.push_back(u1); 17 cout << endl; 18 19 User u2("Bob"); 20 u2.set_email(); 21 u2.change_password(); 22 user_1st.push_back(u1); 23 cout << endl; 24 25 User u3("Hellen"); 26 u2.set_email(); 27 u2.change_password(); 28 user_1st.push_back(u3); 29 cout << endl; 30 31 cout << "There are " << user_1st.size() << "users.they are: " << endl; 32 for (auto& i : user_1st) { 33 i.display(); 34 cout << endl; 35 } 36 } 37 38 int main() { 39 test(); 40 }
1 // 6_25.cpp 2 3 #include "account.h" 4 #include <iostream> 5 6 using namespace std; 7 int main() { 8 Date date(2008, 11, 1); // 起始日期 9 10 // 建立几个账户 11 SavingsAccount accounts[] = { 12 SavingsAccount(date, "03755217", 0.015), 13 SavingsAccount(date, "02343342", 0.015) 14 }; 15 16 const int n = sizeof(accounts) / sizeof(SavingsAccount); // 账户总数 17 18 // 11月的几笔账目 19 accounts[0].deposit(Date(2008, 11, 5), 5000, "salary"); 20 accounts[1].deposit(Date(2008, 11, 25), 10000, "sell stock 0323"); 21 22 23 // 12月的几笔账目 24 accounts[0].deposit(Date(2008, 12, 5), 5500, "salary"); 25 accounts[1].withdraw(Date(2008, 12, 20), 4000, "buy a laptop"); 26 27 // 结算所有账户并输出各个账户信息 28 cout << endl; 29 30 for (int i = 0; i < n; i++) { 31 accounts[i].settle(Date(2009, 1, 1)); 32 accounts[i].show(); 33 cout << endl; 34 } 35 36 cout << "Total: " << SavingsAccount::getTotal() << endl; 37 38 return 0; 39 } 40 41 // date.h 42 43 #ifndef __DATE_H__ 44 #define __DATE_H__ 45 46 // 日期类 47 class Date { 48 private: 49 int year; // 年 50 int month; // 月 51 int day; // 日 52 int totalDays; // 该日期是从公元元年1月1日开始的第几天 53 54 public: 55 Date(int year, int month, int day); // 用年、月、日构造日期 56 int getYear() const { return year; } 57 int getMonth() const { return month; } 58 int getDay() const { return day; } 59 int getMaxDay() const; // 判断当月有多少天 60 61 // 判断当年是否为闰年 62 bool isLeapYear() const { 63 return year % 4 == 0 && year % 100 != 0 || year % 400 == 0; 64 }; 65 66 void show() const; // 输出当前日期 67 68 // 计算两个日期之间差多少天 69 int distance(const Date& date) const { 70 return totalDays - date.totalDays; 71 } 72 }; 73 74 75 #endif // __DATE_H__ 76 77 #pragma once 78 #define __ACCOUNT_H__ 79 #include "date.h" 80 #include <string> 81 class SavingsAccount { 82 private: 83 std::string id; 84 double balance; 85 double rate; 86 Date lastDate; 87 double accumulation; 88 static double total; 89 void record(const Date& date, double amount, const std::string& desc); 90 void error(const std::string& msg)const; 91 double accumulate(const Date& date)const { 92 return accumulation + balance * date.distance(lastDate); 93 } 94 public: 95 SavingsAccount(const Date& date, const std::string& id, double rate); 96 const std::string& getId() const { return id; } 97 double getBalance() const { return balance;} 98 double getRate()const { return rate; } 99 static double getTotal() { return total;} 100 101 void deposit(const Date& date,double amount, const std::string& desc); 102 void withdraw(const Date& date, double amount, const std::string& desc); 103 void settle(const Date& date); 104 void show()const; 105 }; 106 107 // account.cpp 108 109 #include "account.h" 110 111 #include <cmath> 112 #include <iostream> 113 114 using namespace std; 115 116 double SavingsAccount::total = 0; 117 118 // SavingsAccount类相关成员函数的实现 119 SavingsAccount::SavingsAccount(const Date& date, const string& id, double rate) : id(id), balance(0), rate(rate), lastDate(date), accumulation(0) 120 { 121 date.show(); 122 cout << "\t#" << id << " created" << endl; 123 } 124 125 void SavingsAccount::record(const Date& date, double amount, const string& desc) 126 { 127 accumulation = accumulate(date); 128 lastDate = date; 129 amount = floor(amount * 100 + 0.5) / 100; // 保留小数点后两位 130 balance += amount; 131 total += amount; 132 date.show(); 133 cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl; 134 } 135 136 void SavingsAccount::error(const string& msg) const 137 { 138 cout << "Error(#" << id << "): " << msg << endl; 139 } 140 141 void SavingsAccount::deposit(const Date& date, double amount, const string& desc) 142 { 143 record(date, amount, desc); 144 } 145 146 void SavingsAccount::withdraw(const Date& date, double amount, const string& desc) 147 { 148 if (amount > getBalance()) 149 error("not enough moneny"); 150 else 151 record(date, -amount, desc); 152 } 153 154 void SavingsAccount::settle(const Date& date) 155 { 156 // 计算年息 157 double interest = accumulate(date) * rate / date.distance(Date(date.getYear() - 1, 1, 1)); 158 159 if (interest != 0) 160 record(date, interest, "interest"); 161 162 accumulation = 0; 163 } 164 165 void SavingsAccount::show() const 166 { 167 cout << id << "\tBalance: " << balance; 168 }