实验3

试验任务1:

源代码:

button.hpp:

 1 #pragma once
 2 
 3 #include <iostream>
 4 #include <string>
 5 
 6 class Button
 7 {
 8 public:
 9     Button(const std::string &label_);
10     const std::string &get_label() const;
11     void click();
12 
13 private:
14     std::string label;
15 };
16 
17 Button::Button(const std::string &label_) : label{label_}
18 {
19 }
20 
21 inline const std::string &Button::get_label() const
22 {
23     return label;
24 }
25 
26 inline void Button::click()
27 {
28     std::cout << "Button '" << label << "' clicked\n";
29 }

window.hpp:

 1 #pragma once
 2 
 3 #include <iostream>
 4 #include <vector>
 5 #include <algorithm>
 6 #include "button.hpp"
 7 
 8 // 窗口类
 9 class Window
10 {
11 public:
12     Window(const std::string &title_);
13     void display() const;
14     void close();
15     void add_button(const std::string &label);
16     void click_button(const std::string &label);
17 
18 private:
19     bool has_button(const std::string &label) const;
20 
21 private:
22     std::string title;
23     std::vector<Button> buttons;
24 };
25 
26 Window::Window(const std::string &title_) : title{title_}
27 {
28     buttons.push_back(Button("close"));
29 }
30 
31 inline void Window::display() const
32 {
33     std::string s(40, '*');
34     std::cout << s << std::endl;
35     std::cout << "window : " << title << std::endl;
36     int cnt = 0;
37     for (const auto &button : buttons)
38         std::cout << ++cnt << ". " << button.get_label() << std::endl;
39     std::cout << s << std::endl;
40 }
41 
42 inline void Window::close()
43 {
44     std::cout << "close window '" << title << "'" << std::endl;
45     click_button("close");
46 }
47 
48 inline bool Window::has_button(const std::string &label) const
49 {
50     for (const auto &button : buttons)
51         if (button.get_label() == label)
52             return true;
53 
54     return false;
55 }
56 
57 inline void Window::add_button(const std::string &label)
58 {
59     if (has_button(label))
60         std::cout << "button " << label << " already exists!\n";
61     else
62         buttons.push_back(Button(label));
63 }
64 
65 inline void Window::click_button(const std::string &label)
66 {
67     for (auto &button : buttons)
68         if (button.get_label() == label)
69         {
70             button.click();
71             return;
72         }
73 
74     std::cout << "no button: " << label << std::endl;
75 }

task1.cpp:

 1 #include "window.hpp"
 2 #include <iostream>
 3 #include <windows.h>
 4 
 5 void test()
 6 {
 7     Window w("Demo");
 8     w.add_button("add");
 9     w.add_button("remove");
10     w.add_button("modify");
11     w.add_button("add");
12     w.display();
13     w.close();
14 }
15 
16 int main()
17 {
18     SetConsoleOutputCP(CP_UTF8);
19     std::cout << "用组合类模拟简单GUI:\n";
20     test();
21 }

运行结果:

屏幕截图 2025-11-22 154909

问题1:这个范例中, Window 和 Button 是组合关系吗?
答:是组合关系。
 
问题2: bool has_button(const std::string &label) const; 被设计为私有。 思考并回答:
(1)若将其改为公有接口,有何优点或风险?
答:优点:便于外部的使用和调用,增加了灵活性,在外部可查询按钮是否存在;
       风险:暴露了内部实现的细节,增加了维护的负担。
 
(2)设计类时,如何判断一个成员函数应为 public 还是 private?(可从“用户是否需要”、“是否仅为内部实现细节”、“是否易破坏对象状态”等角度分析。)
答:封装内部逻辑,当后续需要修改实现时,要求不会影响外部用户的代码时用private;当这个函数是类提供给外部的核心功能,需要主动调用时用public。
 
问题3: Button 的接口 const std::string& get_label() const; 返回 const std::string& 。对比以下
两种接口设计在性能和安全性方面的差异并精炼陈述。
接口1: const std::string& get_label() const;
接口2: const std::string get_label() const;
答:接口1不拷贝数据,而接口2拷贝数据。接口1生命周期受到约束;接口2无需考虑生命周期,更安全,但占用额外内存,成本较高。
 
问题4:把代码中所有 xx.push_back(Button(xxx)) 改成 xx.emplace_back(xxx) ,观察程序是否正常运行;查阅资料,回答两种写法的差别。
答:可正常运行。xx.push_back(Button(xxx)) 接受已经构造好的对象,再拷贝/移动构造一次;xx.emplace_back(xxx) 则省去了一次拷贝/移动构造,效率更高。
 
试验任务2:
task2.cpp:
  1 #include <iostream>
  2 #include <vector>
  3 #include <windows.h>
  4 
  5 void test1();
  6 void test2();
  7 void output1(const std::vector<int> &v);
  8 void output2(const std::vector<int> &v);
  9 void output3(const std::vector<std::vector<int>> &v);
 10 
 11 int main()
 12 {
 13     SetConsoleOutputCP(CP_UTF8);
 14     std::cout << "深复制验证1: 标准库vector<int>\n";
 15     test1();
 16 
 17     std::cout << "\n深复制验证2: 标准库vector<int>嵌套使用\n";
 18     test2();
 19 }
 20 
 21 void test1()
 22 {
 23     std::vector<int> v1(5, 42);
 24     const std::vector<int> v2(v1);
 25 
 26     std::cout << "**********拷贝构造后**********\n";
 27     std::cout << "v1: ";
 28     output1(v1);
 29     std::cout << "v2: ";
 30     output1(v2);
 31 
 32     v1.at(0) = -1;
 33 
 34     std::cout << "**********修改v1[0]后**********\n";
 35     std::cout << "v1: ";
 36     output1(v1);
 37     std::cout << "v2: ";
 38     output1(v2);
 39 }
 40 
 41 void test2()
 42 {
 43     std::vector<std::vector<int>> v1{{1, 2, 3}, {4, 5, 6, 7}};
 44     const std::vector<std::vector<int>> v2(v1);
 45 
 46     std::cout << "**********拷贝构造后**********\n";
 47     std::cout << "v1: ";
 48     output3(v1);
 49     std::cout << "v2: ";
 50     output3(v2);
 51 
 52     v1.at(0).push_back(-1);
 53 
 54     std::cout << "**********修改v1[0]后**********\n";
 55     std::cout << "v1: \n";
 56     output3(v1);
 57     std::cout << "v2: \n";
 58     output3(v2);
 59 }
 60 
 61 // 使用xx.at()+循环输出vector<int>数据项
 62 void output1(const std::vector<int> &v)
 63 {
 64     if (v.size() == 0)
 65     {
 66         std::cout << '\n';
 67         return;
 68     }
 69 
 70     std::cout << v.at(0);
 71     for (auto i = 1; i < v.size(); ++i)
 72         std::cout << ", " << v.at(i);
 73     std::cout << '\n';
 74 }
 75 
 76 // 使用迭代器+循环输出vector<int>数据项
 77 void output2(const std::vector<int> &v)
 78 {
 79     if (v.size() == 0)
 80     {
 81         std::cout << '\n';
 82         return;
 83     }
 84 
 85     auto it = v.begin();
 86     std::cout << *it;
 87 
 88     for (it = v.begin() + 1; it != v.end(); ++it)
 89         std::cout << ", " << *it;
 90     std::cout << '\n';
 91 }
 92 
 93 // 使用auto for分行输出vector<vector<int>>数据项
 94 void output3(const std::vector<std::vector<int>> &v)
 95 {
 96     if (v.size() == 0)
 97     {
 98         std::cout << '\n';
 99         return;
100     }
101 
102     for (auto &i : v)
103         output2(i);
104 }

运行结果:

屏幕截图 2025-11-23 223150

问题回答:

1.std::vector<int> v1(5, 42)构造了5个值为42的元素(int类型),是带参数的构造函数,const std::vector<int> v2(v1)是复制构造函数;都含5个值为42的元素。

2.v1.size()和v2.size()都为2,v1[0].size()为3。

3.效果相同,但是v1.at(0)=-1会做越界检查并抛出异常,而v1.[0]=-1不会。

4.(1)能。 v1.at(0)返回vector<int>&,执行完v1.at(0).push_back(-1)后,此时r的最后一个就是-1。

(2)const&避免拷贝,节省了内存,是只读,不可修改被引用对象;但是只能调用const成员对象。

5.(1)深复制。

(2)当 v 是 vector<int> 时, v.at(0) 返回值类型是int&;当 v 是 const vector<int> 时, v.at(0) 返回值类型是const int&;必须提供带 const 修饰的重载版本。

 

 

试验任务3:

vectorInt.hpp:
  1 #pragma once
  2 
  3 #include <iostream>
  4 
  5 // 动态int数组对象类
  6 class vectorInt
  7 {
  8 public:
  9     vectorInt();
 10     vectorInt(int n_);
 11     vectorInt(int n_, int value);
 12     vectorInt(const vectorInt &vi);
 13     ~vectorInt();
 14 
 15     int size() const;
 16     int &at(int index);
 17     const int &at(int index) const;
 18     vectorInt &assign(const vectorInt &vi);
 19 
 20     int *begin();
 21     int *end();
 22     const int *begin() const;
 23     const int *end() const;
 24 
 25 private:
 26     int n;    // 当前数据项个数
 27     int *ptr; // 数据区
 28 };
 29 
 30 vectorInt::vectorInt() : n{0}, ptr{nullptr}
 31 {
 32 }
 33 
 34 vectorInt::vectorInt(int n_) : n{n_}, ptr{new int[n]}
 35 {
 36 }
 37 
 38 vectorInt::vectorInt(int n_, int value) : n{n_}, ptr{new int[n_]}
 39 {
 40     for (auto i = 0; i < n; ++i)
 41         ptr[i] = value;
 42 }
 43 
 44 vectorInt::vectorInt(const vectorInt &vi) : n{vi.n}, ptr{new int[n]}
 45 {
 46     for (auto i = 0; i < n; ++i)
 47         ptr[i] = vi.ptr[i];
 48 }
 49 
 50 vectorInt::~vectorInt()
 51 {
 52     delete[] ptr;
 53 }
 54 
 55 int vectorInt::size() const
 56 {
 57     return n;
 58 }
 59 
 60 const int &vectorInt::at(int index) const
 61 {
 62     if (index < 0 || index >= n)
 63     {
 64         std::cerr << "IndexError: index out of range\n";
 65         std::exit(1);
 66     }
 67 
 68     return ptr[index];
 69 }
 70 
 71 int &vectorInt::at(int index)
 72 {
 73     if (index < 0 || index >= n)
 74     {
 75         std::cerr << "IndexError: index out of range\n";
 76         std::exit(1);
 77     }
 78 
 79     return ptr[index];
 80 }
 81 
 82 vectorInt &vectorInt::assign(const vectorInt &vi)
 83 {
 84     if (this == &vi)
 85         return *this;
 86 
 87     int *ptr_tmp;
 88     ptr_tmp = new int[vi.n];
 89     for (int i = 0; i < vi.n; ++i)
 90         ptr_tmp[i] = vi.ptr[i];
 91 
 92     delete[] ptr;
 93     n = vi.n;
 94     ptr = ptr_tmp;
 95     return *this;
 96 }
 97 
 98 int *vectorInt::begin()
 99 {
100     return ptr;
101 }
102 
103 int *vectorInt::end()
104 {
105     return ptr + n;
106 }
107 
108 const int *vectorInt::begin() const
109 {
110     return ptr;
111 }
112 
113 const int *vectorInt::end() const
114 {
115     return ptr + n;
116 }
task3.cpp:
 1 #include "vectorInt.hpp"
 2 #include <iostream>
 3 #include <windows.h>
 4 
 5 void test1();
 6 void test2();
 7 void output1(const vectorInt &vi);
 8 void output2(const vectorInt &vi);
 9 
10 int main()
11 {
12     SetConsoleOutputCP(CP_UTF8);
13     std::cout << "测试1: \n";
14     test1();
15 
16     std::cout << "\n测试2: \n";
17     test2();
18 }
19 
20 void test1()
21 {
22     int n;
23     std::cout << "Enter n: ";
24     std::cin >> n;
25 
26     vectorInt x1(n);
27     for (auto i = 0; i < n; ++i)
28         x1.at(i) = (i + 1) * 10;
29     std::cout << "x1: ";
30     output1(x1);
31 
32     vectorInt x2(n, 42);
33     vectorInt x3(x2);
34     x2.at(0) = -1;
35     std::cout << "x2: ";
36     output1(x2);
37     std::cout << "x3: ";
38     output1(x3);
39 }
40 
41 void test2()
42 {
43     const vectorInt x(5, 42);
44     vectorInt y;
45 
46     y.assign(x);
47 
48     std::cout << "x: ";
49     output2(x);
50     std::cout << "y: ";
51     output2(y);
52 }
53 
54 // 使用xx.at()+循环输出vectorInt对象数据项
55 void output1(const vectorInt &vi)
56 {
57     if (vi.size() == 0)
58     {
59         std::cout << '\n';
60         return;
61     }
62 
63     std::cout << vi.at(0);
64     for (auto i = 1; i < vi.size(); ++i)
65         std::cout << ", " << vi.at(i);
66     std::cout << '\n';
67 }
68 
69 // 使用迭代器+循环输出vectorInt对象数据项
70 void output2(const vectorInt &vi)
71 {
72     if (vi.size() == 0)
73     {
74         std::cout << '\n';
75         return;
76     }
77 
78     auto it = vi.begin();
79     std::cout << *it;
80 
81     for (it = vi.begin() + 1; it != vi.end(); ++it)
82         std::cout << ", " << *it;
83     std::cout << '\n';
84 }

运行结果:

屏幕截图 2025-11-24 172913

问题回答:

1.assign的版本2没有进行是否是自赋值的判断。如果是自赋值的话,一开始就释放数据,会导致数据异常释放,无法完成相关操作。

2.(1)static_cast<const vectorInt*>(this)把this类型从vectorInt*转换为const vectorInt*;

            转换前:vectorInt*,转换后:const vectorInt*;

            其目的是为了能够调用 at 函数的 const 版本。

(2) const_cast<int&>是为了去除const;

           转换前:const int&;转换后:int&;

           目的是为了移除const限定,同时返回int&类型。

3.(1)v1调用非const接口,适用于需要修改元素;v2调用const接口,适用于仅读取,不修改对象状态。

4.可以。std::fill_n(ptr, n, value)表示从ptr指向的位置开始,连续填充n个值为value的数据;

              std::copy_n(vi.ptr, vi.n, ptr)表示从vi.ptr开始,连续复制n个值给ptr;

              std::copy_n(vi.ptr, vi.n, ptr_tmp)表示将vi 的数据复制到临时分配的内存 ptr_tmp 中。

 

 

试验任务4:

matrix.hpp:
  1 #pragma once
  2 
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cstdlib>
  6 
  7 // 类Matrix声明
  8 class Matrix
  9 {
 10 public:
 11     Matrix(int rows_, int cols_, double value = 0); // 构造rows_*cols_矩阵对象, 初值value
 12     Matrix(int rows_, double value = 0);            // 构造rows_*rows_方阵对象, 初值value
 13     Matrix(const Matrix &x);                        // 深复制
 14     ~Matrix();
 15 
 16     void set(const double *pvalue, int size); // 按行复制pvalue指向的数据,要求size=rows*cols,否则报错退出
 17     void clear();                             // 矩阵对象数据项置0
 18 
 19     const double &at(int i, int j) const; // 返回矩阵对象索引(i,j)对应的数据项const引用(越界则报错后退出)
 20     double &at(int i, int j);             // 返回矩阵对象索引(i,j)对应的数据项引用(越界则报错后退出)
 21 
 22     int rows() const; // 返回矩阵对象行数
 23     int cols() const; // 返回矩阵对象列数
 24 
 25     void print() const; // 按行打印数据
 26 
 27 private:
 28     int n_rows;  // 矩阵对象内元素行数
 29     int n_cols;  // 矩阵对象内元素列数
 30     double *ptr; // 数据区
 31 };
 32 
 33 Matrix::Matrix(int rows_, int cols_, double value): n_rows(rows_), n_cols(cols_)
 34 {
 35     ptr = new double[n_rows * n_cols];
 36     std::fill(ptr, ptr + n_rows * n_cols, value);
 37 }
 38 
 39 Matrix::Matrix(int rows_, double value): Matrix(rows_, rows_, value)
 40 {
 41 }
 42 
 43 Matrix::Matrix(const Matrix &x): n_rows(x.n_rows), n_cols(x.n_cols)
 44 {
 45     ptr = new double[n_rows * n_cols];
 46     std::copy(x.ptr, x.ptr + n_rows * n_cols, ptr);
 47 }
 48 
 49 Matrix::~Matrix()
 50 {
 51     delete[] ptr;
 52 }
 53 
 54 void Matrix::set(const double *pvalue, int size)
 55 {
 56     if (size != n_rows * n_cols)
 57     {
 58         std::cerr << "ERROR!" << std::endl;
 59         std::exit(-1);
 60     }
 61     std::copy(pvalue, pvalue + size, ptr);
 62 }
 63 
 64 void Matrix::clear()
 65 {
 66     std::fill(ptr, ptr + n_rows * n_cols, 0);
 67 }
 68 
 69 double &Matrix::at(int i, int j) 
 70 {
 71     return const_cast<double &>(static_cast<const Matrix *>(this)->at(i, j));
 72 }
 73 
 74 const double &Matrix::at(int i, int j) const
 75 {
 76     if (i < 0 || i >= n_rows || j < 0 || j >= n_cols)
 77     {
 78         std::cerr << "IndexError: index out of range\n";
 79         std::exit(1);
 80     }
 81     return ptr[i * n_cols + j];
 82 }
 83 
 84 int Matrix::rows() const
 85 {
 86     return n_rows;
 87 }
 88 
 89 int Matrix::cols() const
 90 {
 91     return n_cols;
 92 }
 93 
 94 void Matrix::print() const
 95 {
 96     for (int i = 0; i < n_rows; ++i)
 97     {
 98         for (int j = 0; j < n_cols; ++j)
 99         {
100             std::cout << at(i, j) << " ";
101         }
102         std::cout << "\n";
103     }
104 }

task4.cpp:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include "matrix.hpp"
 4 #include <windows.h>
 5 
 6 void test1();
 7 void test2();
 8 void output(const Matrix &m, int row_index);
 9 
10 int main()
11 {
12     SetConsoleOutputCP(CP_UTF8);
13     std::cout << "测试1: \n";
14     test1();
15 
16     std::cout << "\n测试2: \n";
17     test2();
18 }
19 
20 void test1()
21 {
22     double x[1000] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
23 
24     int n, m;
25     std::cout << "Enter n and m: ";
26     std::cin >> n >> m;
27 
28     Matrix m1(n, m);  // 创建矩阵对象m1, 大小n×m
29     m1.set(x, n * m); // 用一维数组x的值按行为矩阵m1赋值
30 
31     Matrix m2(m, n);  // 创建矩阵对象m2, 大小m×n
32     m2.set(x, m * n); // 用一维数组x的值按行为矩阵m1赋值
33 
34     Matrix m3(n);     // 创建一个n×n方阵对象
35     m3.set(x, n * n); // 用一维数组x的值按行为矩阵m3赋值
36 
37     std::cout << "矩阵对象m1: \n";
38     m1.print();
39     std::cout << "矩阵对象m2: \n";
40     m2.print();
41     std::cout << "矩阵对象m3: \n";
42     m3.print();
43 }
44 
45 void test2()
46 {
47     Matrix m1(2, 3, -1);
48     const Matrix m2(m1);
49 
50     std::cout << "矩阵对象m1: \n";
51     m1.print();
52     std::cout << "矩阵对象m2: \n";
53     m2.print();
54 
55     m1.clear();
56     m1.at(0, 0) = 1;
57 
58     std::cout << "m1更新后: \n";
59     std::cout << "矩阵对象m1第0行 ";
60     output(m1, 0);
61     std::cout << "矩阵对象m2第0行: ";
62     output(m2, 0);
63 }
64 
65 // 输出矩阵对象row_index行所有元素
66 void output(const Matrix &m, int row_index)
67 {
68     if (row_index < 0 || row_index >= m.rows())
69     {
70         std::cerr << "IndexError: row index out of range\n";
71         exit(1);
72     }
73 
74     std::cout << m.at(row_index, 0);
75     for (int j = 1; j < m.cols(); ++j)
76         std::cout << ", " << m.at(row_index, j);
77     std::cout << '\n';
78 }

运行结果:

屏幕截图 2025-11-24 191322

 

 

试验任务5:

contact.hpp:
 1 #pragma once
 2 
 3 #include <iostream>
 4 #include <string>
 5 
 6 // 联系人类
 7 class Contact
 8 {
 9 public:
10     Contact(const std::string &name_, const std::string &phone_);
11 
12     const std::string &get_name() const;
13     const std::string &get_phone() const;
14     void display() const;
15 
16 private:
17     std::string name;  // 必填项
18     std::string phone; // 必填项
19 };
20 
21 Contact::Contact(const std::string &name_, const std::string &phone_) : name{name_}, phone{phone_}
22 {
23 }
24 
25 const std::string &Contact::get_name() const
26 {
27     return name;
28 }
29 
30 const std::string &Contact::get_phone() const
31 {
32     return phone;
33 }
34 
35 void Contact::display() const
36 {
37     std::cout << name << ", " << phone;
38 }
contactBook.hpp:
  1 #pragma once
  2 
  3 #include <iostream>
  4 #include <string>
  5 #include <vector>
  6 #include <algorithm>
  7 #include "contact.hpp"
  8 
  9 // 通讯录类
 10 class ContactBook
 11 {
 12 public:
 13     void add(const std::string &name, const std::string &phone); // 添加联系人
 14     void remove(const std::string &name);                        // 移除联系人
 15     void find(const std::string &name) const;                    // 查找联系人
 16     void display() const;                                        // 显示所有联系人
 17     size_t size() const;
 18 
 19 private:
 20     int index(const std::string &name) const; // 返回联系人在contacts内索引,如不存在,返回-1
 21     void sort();                              // 按姓名字典序升序排序通讯录
 22 
 23 private:
 24     std::vector<Contact> contacts;
 25 };
 26 
 27 void ContactBook::add(const std::string &name, const std::string &phone)
 28 {
 29     if (index(name) == -1)
 30     {
 31         contacts.push_back(Contact(name, phone));
 32         std::cout << name << " add successfully.\n";
 33         sort();
 34         return;
 35     }
 36 
 37     std::cout << name << " already exists. fail to add!\n";
 38 }
 39 
 40 void ContactBook::remove(const std::string &name)
 41 {
 42     int i = index(name);
 43 
 44     if (i == -1)
 45     {
 46         std::cout << name << " not found, fail to remove!\n";
 47         return;
 48     }
 49 
 50     contacts.erase(contacts.begin() + i);
 51     std::cout << name << " remove successfully.\n";
 52 }
 53 
 54 void ContactBook::find(const std::string &name) const
 55 {
 56     int i = index(name);
 57 
 58     if (i == -1)
 59     {
 60         std::cout << name << " not found!\n";
 61         return;
 62     }
 63 
 64     contacts[i].display();
 65     std::cout << '\n';
 66 }
 67 
 68 void ContactBook::display() const
 69 {
 70     for (auto &c : contacts)
 71     {
 72         c.display();
 73         std::cout << '\n';
 74     }
 75 }
 76 
 77 size_t ContactBook::size() const
 78 {
 79     return contacts.size();
 80 }
 81 
 82 // 待补足1:int index(const std::string &name) const;实现
 83 // 返回联系人在contacts内索引; 如不存在,返回-1
 84 int ContactBook::index(const std::string &name) const
 85 {
 86     for (size_t i = 0; i < contacts.size(); ++i)
 87     {
 88         if (contacts[i].get_name() == name)
 89         {
 90             return i;
 91         }
 92     }
 93     return -1;
 94 }
 95 
 96 // 待补足2:void ContactBook::sort();实现
 97 // 按姓名字典序升序排序通讯录
 98 void ContactBook::sort()
 99 {
100     std::sort(contacts.begin(), contacts.end(), [](const Contact &a, const Contact &b) {
101         return a.get_name() < b.get_name();
102     });
103 }
task5.cpp:
 1 #include "contactBook.hpp"
 2 
 3 void test()
 4 {
 5     ContactBook contactbook;
 6 
 7     std::cout << "1. add contacts\n";
 8     contactbook.add("Bob", "18199357253");
 9     contactbook.add("Alice", "17300886371");
10     contactbook.add("Linda", "18184538072");
11     contactbook.add("Alice", "17300886371");
12 
13     std::cout << "\n2. display contacts\n";
14     std::cout << "There are " << contactbook.size() << " contacts.\n";
15     contactbook.display();
16 
17     std::cout << "\n3. find contacts\n";
18     contactbook.find("Bob");
19     contactbook.find("David");
20 
21     std::cout << "\n4. remove contact\n";
22     contactbook.remove("Bob");
23     contactbook.remove("David");
24 }
25 
26 int main()
27 {
28     test();
29 }

运行结果:

屏幕截图 2025-11-24 193327

 

posted @ 2025-11-24 19:36  noeleven  阅读(3)  评论(0)    收藏  举报