oop-实验3

task1

Button.hpp

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

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 public:
11     Window(const std::string &title);
12     void display() const;
13     void close();
14     void add_button(const std::string &label);
15     void click_button(const std::string &label);
16 private:
17     bool has_button(const std::string &label) const;
18 
19 private:
20     std::string title;
21     std::vector<Button> buttons;
22 };
23 
24 Window::Window(const std::string &title):title{title}{ buttons.push_back(Button("close")); }
25 
26 inline void Window::display() const{
27     std::string s(40,'*');
28     std::cout<<s<<std::endl;
29     std::cout<<"window:"<<title<<std::endl;
30     int cnt=0;
31     for(const auto &button:buttons){
32         std::cout<<++cnt<<"."<<button.get_label()<<std::endl;
33     }
34     std::cout<<s<<std::endl;
35 }
36 
37 inline void Window::close() {
38     std::cout<<"close window "<<title<<std::endl;
39     click_button("close");
40 }
41 
42 inline bool Window::has_button(const std::string &label) const {
43     for(const auto &button: buttons)
44         if(button.get_label() == label)
45             return true;
46     return false;
47 }
48 
49 inline void Window::add_button(const std::string &label) {
50     if(has_button(label))
51         std::cout << "button " << label << " already exists!\n";
52     else buttons.push_back(Button(label));
53 }
54 
55 inline void Window::click_button(const std::string &label) {
56     for(auto &button:buttons)
57         if(button.get_label() == label) {
58             button.click();
59         return;
60     }
61     std::cout << "no button: " << label << std::endl;
62 }

task1.cpp

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

 运行截图:

image

 问题回答:

image

 

 

task2

task2.cpp

 1 #include<iostream>
 2 #include<vector>
 3 
 4 void test1();
 5 void test2();
 6 void output1(const std::vector<int> &v);
 7 void output2(const std::vector<int> &v);
 8 void output3(const std::vector<std::vector<int>> &v);
 9 
10 int main(){
11     std::cout<<"深复制验证1: 标准库vector<int>\n";
12     test1();
13     std::cout<<"\n深复制验证2: 标准库vector<int>嵌套使用\n";
14     test2();
15 }
16 
17 void test1(){
18     std::vector<int> v1(5,42);
19     const std::vector<int> v2(v1);
20 
21     std::cout << "**********拷贝构造后**********\n";
22     std::cout << "v1: "; output1(v1);
23     std::cout << "v2: "; output1(v2);
24 
25     v1.at(0)=-1;
26     std::cout<<"**********修改v1[0]后**********\n";
27     std::cout<<"v1:"; output1(v1);
28     std::cout<<"v2:"; output1(v2);
29 }
30 
31 void test2(){
32     std::vector<std::vector<int>> v1{{1,2,3},{4,5,6,7}};
33     const std::vector<std::vector<int>> v2(v1);
34     std::cout << "**********拷贝构造后**********\n";
35     std::cout << "v1: "; output3(v1);
36     std::cout << "v2: "; output3(v2);
37 
38     v1.at(0).push_back(-1);
39     std::cout << "**********修改v1[0]后**********\n";
40     std::cout << "v1: \n"; output3(v1);
41     std::cout << "v2: \n"; output3(v2);
42 }
43 
44 //at
45 void output1(const std::vector<int> &v){
46     if(v.size()==0){
47         std::cout<<'\n';
48         return;
49     }
50     std::cout<<v.at(0);  //test1中只修改了v1
51     for(auto i=1;i<v.size();i++){
52         std::cout<<","<<v.at(i);
53     }
54     std::cout<<"\n";
55 }
56 //iterator
57 void output2(const std::vector<int> &v){
58     if(v.size()==0){
59         std::cout<<'\n';
60         return;
61     }
62     auto it=v.begin();
63     std::cout<<*it;
64     for(it=v.begin()+1;it!=v.end();++it)
65         std::cout<<","<<*it;
66     std::cout<<'\n';
67 }
68 
69 //print vector<vector<int>>数据项 
70 void output3(const std::vector<std::vector<int>> &v){
71     if(v.size() == 0) {
72         std::cout << '\n';
73         return;
74     }
75     for(auto &i: v)
76         output2(i);
77 }

运行截图:

image

 问题回答:

image

 

 

 task3

 vectorInt.hpp

 1 #pragma once
 2 
 3 #include <iostream>
 4 
 5 class vectorInt{
 6 public:
 7     vectorInt();
 8     vectorInt(int n);
 9     vectorInt(int n,int value);
10     vectorInt(const vectorInt& vi); //深拷贝
11     ~vectorInt();
12 
13     int size() const;
14     int& at(int index);
15     const int& at(int index) const;
16     vectorInt& assign(const vectorInt& vi);
17 
18     int *begin();
19     int *end();
20     const int *begin() const;
21     const int *end() const;
22 private:
23     int n; //当前数据项的个数
24     int *ptr; //数据区
25 };
26 
27 vectorInt::vectorInt():n{0},ptr(nullptr){}
28 vectorInt::vectorInt(int n):n{n},ptr{new int[n]}{}
29 
30 vectorInt::vectorInt(int n,int value):n{n},ptr{new int[n]}{
31     for(int i=0;i<n;i++) ptr[i]=value;
32 }
33 
34 vectorInt::vectorInt(const vectorInt& vi):n{vi.n},ptr{new int[n]}{
35     for(int i=0;i<n;i++) ptr[i]=vi.ptr[i];
36 }
37 
38 vectorInt::~vectorInt(){
39     delete[] ptr;
40 }
41 int vectorInt::size() const{ return n; }
42 
43 const int& vectorInt::at(int index)  const{
44     if(index<0||index>=n){
45         std::cerr<<"IndexError:index out of range\n";
46         std::exit(1);
47     }
48     return ptr[index];
49 }
50 
51 int& vectorInt::at(int index){
52     if(index<0||index>=n){
53         std::cerr<<"IndexError:index out of range\n";
54         std::exit(1);
55     }
56     return ptr[index];
57 }
58 
59 //深拷贝
60 vectorInt& vectorInt::assign(const vectorInt& vi){
61     if (this==&vi) return *this;
62     int *ptr_tmp;
63     ptr_tmp=new int[vi.n];
64     for(int i=0;i<vi.n;i++)
65         ptr_tmp[i]=vi.ptr[i];
66     delete[] ptr;  //将原来自己分配的数组资源释放掉
67     n=vi.n;
68     ptr=ptr_tmp;
69     return *this;
70 }
71 
72 int *vectorInt::begin(){ return ptr; }
73 int *vectorInt::end(){ return ptr+n; }
74 const int *vectorInt::begin() const{ return ptr; }
75 const int *vectorInt::end() const{ return ptr+n; }

task3.cpp

 1 #include"vectorInt.hpp"
 2 #include<iostream>
 3 
 4 void test1();
 5 void test2();
 6 void output1(const vectorInt &vi);
 7 void output2(const vectorInt &vi);
 8 int main() {
 9     std::cout << "测试1: \n";
10     test1();
11     std::cout << "\n测试2: \n";
12     test2();
13 }
14 void test1() {
15     int n;
16     std::cout << "Enter n: ";
17     std::cin >> n;
18     vectorInt x1(n);
19     for(auto i = 0; i < n; ++i)
20         x1.at(i) = (i+1)*10;
21     std::cout << "x1: "; output1(x1);
22     vectorInt x2(n, 42);
23     vectorInt x3(x2);
24     x2.at(0) = -1;
25     std::cout << "x2: "; output1(x2);
26     std::cout << "x3: "; output1(x3);
27 }
28 void test2() {
29     const vectorInt x(5, 42);
30     vectorInt y;
31     y.assign(x);
32     std::cout << "x: "; output2(x);
33     std::cout << "y: "; output2(y);
34 }
35 
36 // 使用xx.at()+循环输出vectorInt对象数据项
37 void output1(const vectorInt &vi) {
38     if(vi.size() == 0) {
39         std::cout << '\n';
40         return;
41     }
42     std::cout << vi.at(0);
43     for(auto i = 1; i < vi.size(); ++i)
44         std::cout << ", " << vi.at(i);
45     std::cout << '\n';
46 }
47 // 使用迭代器+循环输出vectorInt对象数据项
48 void output2(const vectorInt &vi) {
49     if(vi.size() == 0) {
50         std::cout << '\n';
51         return;
52     }
53     auto it = vi.begin();
54     std::cout << *it;
55     for(it = vi.begin()+1; it != vi.end(); ++it)
56         std::cout << ", " << *it;
57     std::cout << '\n';
58 }

运行截图:

 屏幕截图 2025-11-20 095955

问题回答:

image

 

 

task4

Matrix.hpp

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

task4.cpp

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

运行截图:

image

 

 

task5

Contact.hpp

 1 #pragma once
 2 
 3 #include<iostream>
 4 #include<string>
 5 
 6 //联系人
 7 class Contact{
 8 public:
 9     Contact(const std::string &name_,const std::string &phone);
10     const std::string &get_name() const;
11     const std::string &get_phone() const;
12     void display() const;
13 
14 private:
15     std::string name;
16     std::string phone;
17 };
18 
19 Contact::Contact(const std::string &name_,const std::string &phone_):name{name_},phone{phone_} {}
20 
21 const std::string &Contact::get_name() const{
22     return name;
23 }
24 
25 const std::string&Contact::get_phone() const{
26     return phone;
27 }
28 
29 void Contact::display() const{
30     std::cout<<name<<","<<phone;
31 }

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 public:
12     void add(const std::string &name,const std::string &phone); //添加联系人
13     void remove(const std::string &name); //移除联系人
14     void find(const std::string &name) const; //查找
15     void display() const; //显示所有联系人
16     size_t size() const;
17 private:
18     int index(const std::string &name) const; //返回联系人在contacts内索引,如果不存在,返回-1
19     void sort(); //按姓名字典序升序排序通讯录
20 private:
21     std::vector<Contact> contacts;
22 };
23 
24 void ContactBook::add(const std::string &name,const std::string &phone){
25     if(index(name)==-1){
26         contacts.push_back(Contact(name,phone));
27         std::cout<<name<<" add successfully.\n";
28         sort();
29         return;
30     }
31     std::cout<<name<<" already exists. fail to add!\n";
32 }
33 
34 void ContactBook::remove(const std::string &name){
35     int i=index(name);
36     if(i==-1){
37         std::cout<<name<<" not found,fail to remove!\n";
38         return;
39     }
40     contacts.erase(contacts.begin()+i);
41     std::cout<<name<<" remove successfully.\n";
42 }
43 
44 void ContactBook::find(const std::string &name) const{
45     int i=index(name);
46     if(i==-1){
47         std::cout<<name<<" not found!\n";
48         return ;
49     }
50     contacts[i].display();
51     std::cout<<'\n';
52 }
53 
54 void ContactBook::display() const{
55     for(auto &c:contacts){
56         c.display();
57         std::cout<<'\n';
58     }
59 }
60 
61 size_t ContactBook::size() const{
62     return contacts.size();
63 }
64 
65 int ContactBook::index(const std::string &name) const{
66     for(int i=0;i<contacts.size();i++){
67         if(name==contacts[i].get_name()) return i;
68     }
69     return -1;
70 }
71 
72 void ContactBook::sort(){
73     std::sort(contacts.begin(),contacts.end(),[](const Contact& c1,const Contact& c2){
74         return c1.get_name()<c2.get_name();
75     });    
76 }

task5.cpp

 1 #include "contactBook.hpp"
 2 
 3 void test() {
 4     ContactBook contactbook;
 5 
 6     std::cout << "1. add contacts\n";
 7     contactbook.add("Bob", "18199357253");
 8     contactbook.add("Alice", "17300886371");
 9     contactbook.add("Linda", "18184538072");
10     contactbook.add("Alice", "17300886371");
11 
12     std::cout << "\n2. display contacts\n";
13     std::cout << "There are " << contactbook.size() << " contacts.\n";
14     contactbook.display();
15 
16     std::cout << "\n3. find contacts\n";
17     contactbook.find("Bob");
18     contactbook.find("David");
19 
20     std::cout << "\n4. remove contact\n";
21     contactbook.remove("Bob");
22     contactbook.remove("David");
23 }
24 
25 int main() {
26     test();
27 }

运行截图:

image

 

posted @ 2025-11-20 15:54  fg-ever  阅读(14)  评论(0)    收藏  举报