實驗3 類和物件

易安135發表於2024-11-10

實驗任務1:

程式碼:

 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 }
 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 
30     cout << s << endl;
31     cout << "window title:" << title << endl;
32     cout << "It has " << buttons.size() << " buttons:"<<endl;
33     for (const auto& i : buttons)
34         cout << i.get_label() << " button " << endl;
35     cout << s << endl;
36 }
37 
38 void window::close() {
39     cout << "close window '" << title << "'" << endl;
40     buttons.at(0).click();
41 }
42 
43 void window::add_button(const string& label) {
44     buttons.push_back(Button(label));
45 }
 1 #define _CRT_SECURE_NO_WARNINGS 1
 2 
 3 #include "window.hpp"
 4 #include<iostream>
 5 
 6 using std::cout;
 7 using std::cin;
 8 
 9 void test() {
10     window w1("new window");
11     w1.add_button("maximize");
12     w1.display();
13     w1.close();
14 }
15 
16 int main() {
17     cout << "用組合類模擬簡單GUI:\n";
18     test();
19 }

截圖:

問題1:

兩個類(button和window)vector,string.button和string,window和button以及string以及vector.

問題2:

不合適。因為加了const之後不可修改,加了inline是為了提高效率,對於較複雜的程式隨意加上這兩個關鍵字可能會出錯。

問題3:

建立1個string s,內容是40個*,分開各部分程式碼。

實驗任務2:

程式碼:

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

截圖:

問題1:
21:建立一個元素為整型的可變長陣列v1,元素是5個42;

22:建立一個元素為整型的可變長陣列v2,元素與v1相同,是5個42;

24:將v1的第一個數改為-999.

問題2:

建立一個元素為元素是可變長陣列容器的可變長陣列容器v1,元素是{1,2,3}和{4,5,6,7};

建立一個元素為元素是可變長陣列容器的可變長陣列容器v2,深複製v1,元素是{1,2,3}和{4,5,6,7};

將v1第一個元素中的第一個元素改為-999;

問題3:

39,42:得到當前陣列的第一個元素;

40,43:輸出當前陣列的最後一個元素。

問題4:

深複製;需要。

實驗任務3:

程式碼:

 1 #pragma once
 2 
 3 #include<iostream>
 4 #include<cassert>
 5 
 6 using std::cout;
 7 using std::endl;
 8 
 9 //動態int陣列物件類
10 class vectorInt {
11 public:
12     vectorInt(int n);
13     vectorInt(int n, int value);
14     vectorInt(const vectorInt& vi);
15     ~vectorInt();
16 
17     int& at(int index);
18     const int& at(int index) const;
19 
20     vectorInt& assign(const vectorInt& v);
21     int get_size() const;
22 
23 private:
24     int size;
25     int* ptr;        //ptr指向包含size個int的陣列
26 };
27 
28 vectorInt::vectorInt(int n) :size{ n }, ptr{ new int[size] } {
29 }
30 
31 vectorInt::vectorInt(int n,int value) :size{ n }, ptr{ new int[size] } {
32     for (auto i = 0; i < size; i++) {
33         ptr[i] = value;
34     }
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 
43 vectorInt::~vectorInt() {
44     delete[] ptr;
45 }
46 
47 const int& vectorInt::at(int index)const {
48     assert(index >= 0 && index < size);
49 
50     return ptr[index];
51 }
52 
53 int& vectorInt::at(int index){
54     assert(index >= 0 && index < size);
55 
56     return ptr[index];
57 }
58 
59 vectorInt& vectorInt::assign(const vectorInt& v) {
60     delete[] ptr;       //釋放物件中ptr原本指向的資源
61 
62     size = v.size;
63     ptr = new int[size];
64 
65     for (int i = 0; i < size; i++) {
66         ptr[i] = v.ptr[i];
67     }
68 
69     return *this;
70 }
71 
72 int vectorInt::get_size()const {
73     return size;
74 }
 1 #define _CRT_SECURE_NO_WARNINGS 1
 2 
 3 #include"vectorInt.hpp"
 4 #include<iostream>
 5 
 6 using std::cin;
 7 using std::cout;
 8 
 9 void output(const vectorInt& vi) {
10     for (auto i = 0; i < vi.get_size(); i++) {
11         cout << vi.at(i) << ", ";
12     }
13     cout << "\b\b\n";
14 }
15 
16 
17 void test1() {
18     int n;
19     cout << "Enter n: ";
20     cin >> n;
21 
22     vectorInt x1(n);
23     for (auto i = 0; i < n; i++) {
24         x1.at(i) = i * i;
25     }
26     cout << "x1: "; output(x1);
27 
28     vectorInt x2(n, 42);
29     vectorInt x3(x2);
30     x2.at(0) = -999;
31     cout << "x2: ";output(x2);
32     cout << "x3: "; output(x3);
33 }
34 
35 void test2() {
36     const vectorInt x(5, 42);
37     vectorInt y(10, 0);
38 
39     cout << "y: "; output(y);
40     y.assign(x);
41     cout << "y: "; output(y);
42 
43     cout << "x.at(0) = " << x.at(0) << endl;
44     cout << "y.at(0) = " << y.at(0) << endl;
45 }
46 
47 int main() {
48     cout << "測試1:\n";
49     test1();
50 
51     cout << "\n測試2:\n";
52     test2();
53 }

截圖:

問題1:

深複製。

問題2:

不能。會有。

返回int,不能被賦值。

const去掉後,值可能被修改。

問題3:

可以。返回引用用引用接收,返回vectorInt用物件接收,是可以的。

實驗任務4:

程式碼:

 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);
13     Matrix(int n);
14     Matrix(const Matrix& x);
15     ~Matrix();
16 
17     void set(const double *pvalue);
18     void clear();
19 
20     const double& at(int i,int j)const;
21     double& at(int i, int j);
22 
23     int get_lines()const;
24     int get_cols()const;
25 
26     void display()const;
27 private:
28     int lines;
29     int cols;
30     double* ptr;
31 };
32 
33 Matrix::Matrix(int n, int m) :lines{ n }, cols{ m }, ptr{ new double[lines * cols] } {
34     for (int i = 0; i < n * m; i++) {
35         ptr[i] = 1;//設value為1
36     }
37 }
38 
39 Matrix::Matrix(int n) :lines{ n }, cols{ n }, ptr{ new double[n * n] } {
40     for (int i = 0; i < n * n; i++) {
41         ptr[i] = 1;
42     }
43 }
44 
45 Matrix::Matrix(const Matrix &x):lines{ x.lines }, cols{ x.cols }, ptr{ new double[lines*cols] } {
46     for (int i = 0; i < lines*cols; i++) {
47         ptr[i] = x.ptr[i];
48     }
49 }
50 
51 Matrix::~Matrix() {
52     delete[] ptr;
53 }
54 
55 void Matrix::set(const double *pvalue) {
56     for (int i = 0; i < lines * cols; i++) {
57         ptr[i] = pvalue[i];
58     }
59 }
60 
61 void Matrix::clear() {
62     for (int i = 0; i < lines * cols; i++) {
63         ptr[i] = 0;
64     }
65 }
66 
67 const  double& Matrix::at(int i, int j)const {
68     return ptr[i*cols+j];
69 }
70 double& Matrix::at(int i, int j) {
71     return ptr[i * cols + j];
72 }
73 
74 int Matrix::get_lines()const {
75     return lines;
76 }
77 int Matrix::get_cols()const {
78     return cols;
79 }
80 
81 void Matrix::display()const {
82     for (int i = 0; i < lines; i++) {
83         for (int j = 0; j < cols; j++) {
84             cout << ptr[i * cols + j]<<", ";
85         }
86         cout << endl;
87     }
88 }
 1 #define _CRT_SECURE_NO_WARNINGS 1
 2 
 3 #include "matrix.hpp"
 4 #include <iostream>
 5 #include <cassert>
 6 
 7 using std::cin;
 8 using std::cout;
 9 using std::endl;
10 
11 
12 const int N = 1000;
13 
14 // 輸出矩陣物件索引為index所在行的所有元素
15 void output(const Matrix& m, int index) {
16     assert(index >= 0 && index < m.get_lines());
17 
18     for (auto j = 0; j < m.get_cols(); ++j)
19         cout << m.at(index, j) << ", ";
20     cout << "\b\b \n";
21 }
22 
23 
24 void test1() {
25     double x[1000] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
26 
27     int n, m;
28     cout << "Enter n and m: ";
29     cin >> n >> m;
30 
31     Matrix m1(n, m);    // 建立矩陣物件m1, 大小n×m
32     m1.set(x);          // 用一維陣列x的值按行為矩陣m1賦值
33 
34     Matrix m2(m, n);    // 建立矩陣物件m1, 大小m×n
35     m2.set(x);          // 用一維陣列x的值按行為矩陣m1賦值
36 
37     Matrix m3(2);       // 建立一個2×2矩陣物件
38     m3.set(x);          // 用一維陣列x的值按行為矩陣m4賦值
39 
40     cout << "矩陣物件m1: \n";   m1.display();  cout << endl;
41     cout << "矩陣物件m2: \n";   m2.display();  cout << endl;
42     cout << "矩陣物件m3: \n";   m3.display();  cout << endl;
43 }
44 
45 void test2() {
46     Matrix m1(2, 3);
47     m1.clear();
48 
49     const Matrix m2(m1);
50     m1.at(0, 0) = -999;
51 
52     cout << "m1.at(0, 0) = " << m1.at(0, 0) << endl;
53     cout << "m2.at(0, 0) = " << m2.at(0, 0) << endl;
54     cout << "矩陣物件m1第0行: "; output(m1, 0);
55     cout << "矩陣物件m2第0行: "; output(m2, 0);
56 }
57 
58 int main() {
59     cout << "測試1: \n";
60     test1();
61 
62     cout << "測試2: \n";
63     test2();
64 }

截圖:

實驗任務5:

程式碼:

 1 #pragma once
 2 
 3 #include<string>
 4 #include<iostream>
 5 
 6 using namespace std;
 7 
 8 class User{
 9 public:
10     User(const string name1) :name{ name1 } {
11         password = "123456";
12     }
13     User(const string name1, const string password1, const string email1) :name{ name1 }, password{ password1 }, email{ email1 } {
14     }
15     void set_email();
16     void change_password();
17     void display();
18     bool isTrueEmail(string newEmail);
19 private:
20     string name;
21     string password;
22     string email;
23 };
24 
25 void User::set_email() {
26     cout << "Enter email address:";
27     string newEmail;
28     cin >> newEmail;
29     while(!isTrueEmail(newEmail)) {
30         cout << "illegal email. Please re-enter email: ";
31         cin >> newEmail;
32     }
33     cout << "email is set successfully..." << endl;
34     email = newEmail;
35 }
36 
37 bool User::isTrueEmail(string newEmail) {
38     for (int i = 0; i < newEmail.size(); i++) {
39         if (newEmail[i]=='@') {
40             return true;
41         }
42     }
43     return false;
44 }
45 
46 void User::change_password() {
47     cout << "Enter old password: ";
48     string newPassword;
49     cin >> newPassword;
50     int count = 0;//count記錄輸入密碼錯誤的次數
51     while (newPassword != password) {
52         count++;
53         cout << "password input error. ";
54         if (count == 3) {
55             cout << "Please try after a while." << endl;
56             return;
57         }
58          cout<<"Please re-enter again : ";
59         cin >> newPassword;
60     }
61     cout << "Enter new password: ";
62     cin >> newPassword;
63     password = newPassword;
64     cout << "new password is set successfully..." << endl;
65 }
66 
67 void User::display() {
68     cout << "name:  " << name << endl;
69     cout << "pass:  ";
70     for (int i = 0; i < password.size(); i++) {
71         cout << "*";
72     }
73     cout << endl;
74     cout << "email  " << email << endl;
75 }
 1 #define _CRT_SECURE_NO_WARNINGS 1
 2 
 3 #include "user.hpp"
 4 #include <iostream>
 5 #include <vector>
 6 #include <string>
 7 
 8 using std::cin;
 9 using std::cout;
10 using std::endl;
11 using std::vector;
12 using std::string;
13 
14 void test() {
15     vector<User> user_lst;
16 
17     User u1("Alice", "2024113", "Alice@hotmail.com");
18     user_lst.push_back(u1);
19     cout << endl;
20 
21     User u2("Bob");
22     u2.set_email();
23     u2.change_password();
24     user_lst.push_back(u2);
25     cout << endl;
26 
27     User u3("Hellen");
28     u3.set_email();
29     u3.change_password();
30     user_lst.push_back(u3);
31     cout << endl;
32 
33     cout << "There are " << user_lst.size() << " users. they are: " << endl;
34     for (auto& i : user_lst) {
35         i.display();
36         cout << endl;
37     }
38 }
39 
40 int main() {
41     test();
42 }

截圖:

實驗任務6:

程式碼:

1 #ifndef __DATE_H__
 2 #define __DATE_H__
 3 class Date {
  private:
      int year;
      int month;
      int day;
      int totalDays;
  public:
     Date(int year, int month, int day);
     int getYear() const { return year; }
     int getMonth() const { return month; }
     int getDay() const { return day; }
     int getMaxDay() const;
     bool isLeapYear() const {
         return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
     }
     void show() const;

         int distance(const Date& date) const {
         return totalDays - date.totalDays;
    }
 };
 #endif //__DATE_H__

 #include "date.h"
  #include <iostream>
  #include <cstdlib>
  using namespace std;
  namespace {
      const int DAYS_BEFORE_MONTH[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
 }
  Date::Date(int year, int month, int day) : year(year), month(month), day(day) {
      if (day <= 0 || day > getMaxDay()) {
         cout << "Invalid date: ";
         show();
         cout << endl;
         exit(1);
     }
     int years = year - 1;
     totalDays = years * 365 + years / 4 - years / 100 + years / 400
                 + DAYS_BEFORE_MONTH[month - 1] + day;
     if (isLeapYear() && month > 2) totalDays++;
 }
 int Date::getMaxDay() const {
     if (isLeapYear() && month == 2)
         return 29;
     else
         return DAYS_BEFORE_MONTH[month]- DAYS_BEFORE_MONTH[month - 1];
 }
 void Date::show() const {
     cout << getYear() << "-" << getMonth() << "-" << getDay();
 }

 #ifndef __ACCOUNT_H__
 #define __ACCOUNT_H__
 #include "date.h"
 #include <string>
    class SavingsAccount {
    private:
        std::string id;
        double balance;
        double rate;
         Date lastDate;
         double accumulation;
         static double total;

         void record(const Date &date, double amount, const std::string &desc);

         void error(const std::string &msg) const;

         double accumulate(const Date& date) const {
             return accumulation + balance * date.distance(lastDate);
         }
     public:

         SavingsAccount(const Date &date, const std::string &id, double rate);
         const std::string &getId() const { return id; }
         double getBalance() const { return balance; }
         double getRate() const { return rate; }
         static double getTotal() { return total; }

         void deposit(const Date &date, double amount, const std::string &desc);

         void withdraw(const Date &date, double amount, const std::string &desc);

         void settle(const Date &date);

         void show() const;
     };
     #endif //__ACCOUNT_H__

 #include "account.h"
 #include <cmath>
    #include <iostream>
    using namespace std;
    double SavingsAccount::total = 0;
    SavingsAccount::SavingsAccount(const Date &date, const string &id, double rate)
            : id(id), balance(0), rate(rate), lastDate(date), accumulation(0) {
        date.show();
         cout << "\t#" << id << " created" << endl;
     }
     void SavingsAccount::record(const Date &date, double amount, const string &desc) {
         accumulation = accumulate(date);
         lastDate = date;
         amount = floor(amount * 100 + 0.5) / 100;
         balance += amount;
         total += amount;
         date.show();
         cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
     }
     void SavingsAccount::error(const string &msg) const {
         cout << "Error(#" << id << "): " << msg << endl;
     }
     void SavingsAccount::deposit(const Date &date, double amount, const string &desc) {
         record(date, amount, desc);
     }
     void SavingsAccount::withdraw(const Date &date, double amount, const string &desc) {
         if (amount > getBalance())
             error("not enough money");
         else
             record(date, -amount, desc);
     }
     void SavingsAccount::settle(const Date &date) {
         double interest = accumulate(date) * rate
                           / date.distance(Date(date.getYear() - 1, 1, 1));
         if (interest != 0)
             record(date, interest, "interest");
         accumulation = 0;
     }
     void SavingsAccount::show() const {
         cout << id << "\tBalance: " << balance;
     }

 #include "account.h"
 #include <iostream>
    using namespace std;
    int main() {
        Date date(2008, 11, 1);
        SavingsAccount accounts[] = {
                SavingsAccount(date, "03755217", 0.015),
                SavingsAccount(date, "02342342", 0.015)
         };
         const int n = sizeof(accounts) / sizeof(SavingsAccount);

         accounts[0].deposit(Date(2008, 11, 5), 5000, "salary");
         accounts[1].deposit(Date(2008, 11, 25), 10000, "sell stock 0323");

         accounts[0].deposit(Date(2008, 12, 5), 5500, "salary");
         accounts[1].withdraw(Date(2008, 12, 20), 4000, "buy a laptop");

         cout << endl;
         for (int i = 0; i < n; i++) {
             accounts[i].settle(Date(2009, 1, 1));
             accounts[i].show();
             cout << endl;
         }
         cout << "Total: " << SavingsAccount::getTotal() << endl;
         return 0;
     }

截圖:

相關文章