实验3 类和对象-基础编程2

news/2024/11/15 9:26:49/文章来源:https://www.cnblogs.com/pzk168/p/18536925

实验任务1:

Button.hpp,Window.hpp,task1.cpp,源码,运行测试结果如下

#pragma once#include <iostream>
#include <string>using std::string;
using std::cout;// 按钮类
class Button {
public:Button(const string &text);string get_label() const;void click();private:string label;
};Button::Button(const string &text): label{text} {
}inline string Button::get_label() const {return label;
}void Button::click() {cout << "Button '" << label << "' clicked\n";
}
Button.hpp
#pragma once
#include "button.hpp"
#include <vector>
#include <iostream>using std::vector;
using std::cout;
using std::endl;// 窗口类
class Window{
public:Window(const string &win_title);void display() const;void close();void add_button(const string &label);private:string title;vector<Button> buttons;
};Window::Window(const string &win_title): title{win_title} {buttons.push_back(Button("close"));
}inline void Window::display() const {string s(40, '*');cout << s << endl;cout << "window title: " << title << endl;cout << "It has " << buttons.size() << " buttons: " << endl;for(const auto &i: buttons)cout << i.get_label() << " button" << endl;cout << s << endl;
}void Window::close() {cout << "close window '" << title << "'" << endl;buttons.at(0).click();
}void Window::add_button(const string &label) {buttons.push_back(Button(label));
}
Window.hpp
#include "window.hpp"
#include <iostream>using std::cout;
using std::cin;void test() {Window w1("new window");w1.add_button("maximize");w1.display();w1.close();
}int main() {cout << "用组合类模拟简单GUI:\n";test();
}
task1.cpp

问题1:

定义了Button和Window两个类;使用到标准库中的string,vector;sting定义了Button中label且在Window中有输出,vector定义了Window中的Buttons,是一个string的vector

问题2:

click()和close()都没必要加const,因为其没有参数传入;它们也没必要加inline,因为只在开头和结尾使用一次。

问题3:

使用string构造一个字符串,第一个参数是字符串长度int,第二个参数是每个位置应填充的字符;代码将创造含四十个连续*的字符串

 

实验任务2:

task2.cpp,源码,运行测试结果如下

#include <iostream>
#include <vector>using namespace std;void output1(const vector<int> &v) {for(auto &i: v)cout << i << ", ";cout << "\b\b \n";
}void output2(const vector<vector<int>> v) {for(auto &i: v) {for(auto &j: i)cout << j << ", ";cout << "\b\b \n";}
}void test1() {vector<int> v1(5, 42);const vector<int> v2(v1);v1.at(0) = -999;cout << "v1: ";  output1(v1);cout << "v2: ";  output1(v2);cout << "v1.at(0) = " << v1.at(0) << endl;cout << "v2.at(0) = " << v2.at(0) << endl;
}void test2() {vector<vector<int>> v1{{1, 2, 3}, {4, 5, 6, 7}};const vector<vector<int>> v2(v1);v1.at(0).push_back(-999);cout << "v1: \n";  output2(v1);cout << "v2: \n";  output2(v2);vector<int> t1 = v1.at(0);cout << t1.at(t1.size()-1) << endl;const vector<int> t2 = v2.at(0);cout << t2.at(t2.size()-1) << endl;
}int main() {cout << "    1:\n";test1();cout << "\n    2:\n";test2();
}
task2.cpp

问题1:

vector<int>v1(5, 42);创造名为v1的一维向量,用五个42填充,const vector<int>v2(v1);创造一个名为v2的一维向量,用v2初始化它,有const修饰不可修改,v1.at(0) = -999;用at成员函数访问v1的第一个元素并将它改为-999

问题2:

vector<vector<int>>v1{ {1,2,3},{4,5,6,7} };创造一个名为v1的二维向量,它包含两个一维向量,分别是{1,2,3}和{4,5,6,7},const vector<vector<int>>v2(v1);创造一个名为v2的二维向量,用v1初始化它,用const修饰不可修改,v1.at(0).push_back(-999);用at成员函数访问v1的第一个一维向量,并向末尾添加-999

 问题3:
line39定义了vector类型的t1,用v1的第一个成员给t1赋初值 line40输出了t1的最后一个元素 line42定义了const修饰的vector类型的t2,用v2的第一个成员给t2赋初值 line43输出了t1的最后一个元素
问题4:
是浅复制,需要
 
实验任务3:
vectorInt.hpp,task3.cpp,源码,运行测试结果如下
#pragma once#include <iostream>
#include <cassert>using std::cout;
using std::endl;// 动态int数组对象类
class vectorInt{
public:vectorInt(int n);vectorInt(int n, int value);vectorInt(const vectorInt &vi);~vectorInt();int& at(int index);const int& at(int index) const;vectorInt& assign(const vectorInt &v);int get_size() const;private:int size;int *ptr;       // ptr指向包含size个int的数组
};vectorInt::vectorInt(int n): size{n}, ptr{new int[size]} {
}vectorInt::vectorInt(int n, int value): size{n}, ptr{new int[size]} {for(auto i = 0; i < size; ++i)ptr[i] = value;
}vectorInt::vectorInt(const vectorInt &vi): size{vi.size}, ptr{new int[size]} {for(auto i = 0; i < size; ++i)ptr[i] = vi.ptr[i];
}vectorInt::~vectorInt() {delete [] ptr;
}const int& vectorInt::at(int index) const {assert(index >= 0 && index < size);return ptr[index];
}int& vectorInt::at(int index) {assert(index >= 0 && index < size);return ptr[index];
}vectorInt& vectorInt::assign(const vectorInt &v) {  delete[] ptr;       // 释放对象中ptr原来指向的资源
size = v.size;ptr = new int[size];for(int i = 0; i < size; ++i)ptr[i] = v.ptr[i];return *this;
}int vectorInt::get_size() const {return size;
}
vectorInt.hpp
#include "vectorInt.hpp"
#include <iostream>using std::cin;
using std::cout;void output(const vectorInt &vi) {for(auto i = 0; i < vi.get_size(); ++i)cout << vi.at(i) << ", ";cout << "\b\b \n";
}void test1() {int n;cout << "Enter n: ";cin >> n;vectorInt x1(n);for(auto i = 0; i < n; ++i)x1.at(i) = i*i;cout << "x1: ";  output(x1);vectorInt x2(n, 42);vectorInt x3(x2);x2.at(0) = -999;cout << "x2: ";  output(x2);cout << "x3: ";  output(x3);
}void test2() {const vectorInt  x(5, 42);vectorInt y(10, 0);cout << "y: ";  output(y);y.assign(x);cout << "y: ";  output(y);cout << "x.at(0) = " << x.at(0) << endl;cout << "y.at(0) = " << y.at(0) << endl;
}int main() {cout << "测试1: \n";test1();cout << "\n测试2: \n";test2();
}
task3.cpp

问题1:

深复制,因为释放了原有资源并且分配了新内存

问题2:

不能。

如果去掉第一个const,那么返回的引用将不再是对常量的引用,调用者可以通过这个引用来修改整数值。这可能会破坏类的封装性,特别是如果这个函数返回的是类的内部数据结构的直接引用的话。如果去掉第二个const,那么该函数将不再是一个常量成员函数,它将能够修改调用它的对象的状态。这可能会导致在不应该修改对象状态的情况下意外地修改了对象,从而引入难以追踪的错误。

问题3:

不可以?运行结果没有出错,但是返回对象会带来不必要的复制,而且如果错误返回对象的引用会导致未定义行为

 

实验任务4:

Matrix.hpp,task4.cpp,源码,运行测试结果如下

#pragma once#include <iostream>
#include <cassert>using std::cout;
using std::endl;// 类Matrix的声明
class Matrix {
public:Matrix(int n, int m);           // 构造函数,构造一个n*m的矩阵, 初始值为valueMatrix(int n);                  // 构造函数,构造一个n*n的矩阵, 初始值为valueMatrix(const Matrix &x);        // 复制构造函数, 使用已有的矩阵X构造~Matrix();void set(const double *pvalue);         // 用pvalue指向的连续内存块数据按行为矩阵赋值void clear();                           // 把矩阵对象的值置0const double& at(int i, int j) const;   // 返回矩阵对象索引(i,j)的元素const引用double& at(int i, int j);               // 返回矩阵对象索引(i,j)的元素引用int get_lines() const;                  // 返回矩阵对象行数int get_cols() const;                   // 返回矩阵对象列数void display() const;                    // 按行显示矩阵对象元素值private:int lines;      // 矩阵对象内元素行数int cols;       // 矩阵对象内元素列数double *ptr;
};
Matrix.hpp
#include "matrix.hpp"
#include <iostream>
#include <cassert>using std::cin;
using std::cout;
using std::endl;const int N = 1000;// 输出矩阵对象索引为index所在行的所有元素
void output(const Matrix &m, int index) {assert(index >= 0 && index < m.get_lines());for(auto j = 0; j < m.get_cols(); ++j)cout << m.at(index, j) << ", ";cout << "\b\b \n";
}void test1() {double x[1000] = {1, 2, 3, 4, 5, 6, 7, 8, 9};int n, m;cout << "Enter n and m: ";cin >> n >> m;Matrix m1(n, m);    // 创建矩阵对象m1, 大小n×mm1.set(x);          // 用一维数组x的值按行为矩阵m1赋值
Matrix m2(m, n);    // 创建矩阵对象m1, 大小m×nm2.set(x);          // 用一维数组x的值按行为矩阵m1赋值
Matrix m3(2);       // 创建一个2×2矩阵对象m3.set(x);          // 用一维数组x的值按行为矩阵m4赋值
cout << "矩阵对象m1: \n";   m1.display();  cout << endl;cout << "矩阵对象m2: \n";   m2.display();  cout << endl;cout << "矩阵对象m3: \n";   m3.display();  cout << endl;
}void test2() {Matrix m1(2, 3);m1.clear();const Matrix m2(m1);m1.at(0, 0) = -999;cout << "m1.at(0, 0) = " << m1.at(0, 0) << endl;cout << "m2.at(0, 0) = " << m2.at(0, 0) << endl;cout << "矩阵对象m1第0行: "; output(m1, 0);cout << "矩阵对象m2第0行: "; output(m2, 0);
}int main() {cout << "测试1: \n";test1();cout << "测试2: \n";test2();
}
task4.cpp

 

实验任务5:

user.hpp,task5.cpp,源码,运行测试结果如下

#include<iostream>
#include<vector>
#include<string>using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;class User{
public:User(string n,string p="123456",string e="NULL");void set_email();void change_password();void display() const;private:string name;string password;string email;};User::User(string n,string p,string e){name=n;password=p;email=e;
}void User::set_email(){string em;cout<<"Enter email address:";while(cin>>em){int count=0;for(int i=0;i<em.size();i++){if(em[i]=='@'){count++;}}if(count){email=em;cout<<"email is set successfully..."<<endl;break;}else{cout<<"illegal email.Please re-enter email:";}}}void User::change_password(){string oe,ne;int count=0;cout<<"Enter old password:";cin>>oe;for(int i=0;i<3;i++){if(oe==password){cout<<"Enter new password:";cin>>ne;email=ne;cout<<"new password is set succesfully"<<endl;break;}else{count++;if(count==3){cout<<"password input error.Please try after a while."<<endl;break;}cout<<"password input error.Please re-enter again:";cin>>oe;}}}void User::display() const{cout<<"name:"<<name<<endl;int i=password.size();for(int j=0;j<i;j++){cout<<"*";}cout<<endl;cout<<"email:"<<email<<endl;
}
user.hpp
#include "user.hpp"
#include <iostream>
#include <vector>
#include <string>using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;void test() {vector<User> user_lst;User u1("Alice", "2024113", "Alice@hotmail.com");user_lst.push_back(u1);cout << endl;User u2("Bob");u2.set_email();u2.change_password();user_lst.push_back(u2);cout << endl;User u3("Hellen");u3.set_email();u3.change_password();user_lst.push_back(u3);cout << endl;cout << "There are " << user_lst.size() << " users. they are: " << endl;for(auto &i: user_lst) {i.display();cout << endl;}
}int main() {test();
}
task5.cpp

 

实验任务6:

data.hpp,account.cpp,task6.cpp,源码,运行测试结果如下

#pragma once 
#include <iostream>  
#include <cstdlib>  
using namespace std;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;}};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;elsereturn DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1];}void Date::show() const {cout << getYear() << "-" << getMonth() << "-" << getDay();}date.hpp
data.hpp
#pragma once  
#include "date.hpp"  
#include <string>  
#include <cmath>  
#include <iostream>  
using namespace std;class SavingsAccount {
private:
string id;double balance;
double rate;Date lastDate;double accumulation;static double total;void record(const Date& date, double amount, const string& desc);void error(const string& msg) const;double accumulate(const Date& date) const {return accumulation + balance * date.distance(lastDate);}public:SavingsAccount(const Date& date, const string& id, double rate);const string& getId() const { return id; }double getRate() const { return rate; }static double getTotal() { return total; }void deposit(const Date& date, double amount, const string& desc);void withdraw(const Date& date, double amount, const string& desc);void settle(const Date& date);void show() const;};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;}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");elserecord(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;}
account.cpp
#include "account.hpp"  
#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;
}task6.cpp
task6.cpp

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/829371.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【论文系列】DDIM ---DDPM上的优化

What DDIM是啥? DDIM(Denoising Diffusion Implicit Models) 是一种扩散模型的变体,旨在加速图像生成过程并保持生成质量。它是在DDPM(Denoising Diffusion Probabilistic Models)的基础上发展出来的,提供了一种更高效的去噪采样过程,减少了采样所需的步骤数量。 Why D…

解决zip解压之后中文乱码问题

1、打开windows 设置 语言和区域2、打开管理语言设置3、取消勾选这个Beta,然后重启即可

VMware ESXi 6.7 U3u (ESXi670-202403001) 下载

VMware ESXi 6.7 U3u (ESXi670-202403001) 下载VMware ESXi 6.7 U3u (ESXi670-202403001) 下载 VMware ESXi 6 Extend Support Release 请访问原文链接:https://sysin.org/blog/vmware-esxi-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org产品简介 VMware ES…

VMware vCenter Server 6.7U3w 发布下载 - ESXi 集中管理软件

VMware vCenter Server 6.7U3w 发布下载 - ESXi 集中管理软件VMware vCenter Server 6.7U3w (安全更新) - ESXi 集中管理软件 集中式控制 vSphere 环境 请访问原文链接:https://sysin.org/blog/vmware-vcenter-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org…

H264码流的RTP封装

H264、RTP、视频编码一、RTP协议头: 1.RTP头定义:RTP协议头一般固定为12个字段,在每一个RTP数据包中都存在。各字段的含义如下: version(V):2bits:标识RTP的版本,当前协议版本固定为2. padding(P):1bits:填充位。默认0,如果为1,则在该报文的末尾填充一个或多个额外的…

批量计算遥感影像NDVI:Python代码

本文介绍基于Python中的gdal模块,批量基于大量多波段遥感影像文件,计算其每1景图像各自的NDVI数值,并将多景结果依次保存为栅格文件的方法~本文介绍基于Python中的gdal模块,批量基于大量多波段遥感影像文件,计算其每1景图像各自的NDVI数值,并将多景结果依次保存为栅格文件…

线程池创建方式

线程池创建方式一、方式一:通过ThreadPoolExecutor构造函数来创建(推荐) 方式二:通过 Executor 框架的工具类 Executors 来创建。Executors工具类提供的创建线程池的方法如下图所示: 可以看出,通过Executors工具类可以创建多种类型的线程池,包括:1. FixedThreadPo…

HTML基础练习

注意:全卷满分140+45分,时间40分钟。 全开卷,并允许联网查询。 凡是标注“不定项”的,每个选项均分总分,每错选或漏选一个均仅扣除该项得分。例如8分4选项题,答案为AD,选ABD得6分,A得6分,AB得4分。 所有题目均为人工阅卷,不需要特别遵守格式规范,均按照答案酌情给分…

将URDF模型文件导入Issac_Gym系列【1】

1 在solidworks中导出URDF文件 1 这里按照古月居老师的要求进行基本的配置 https://www.bilibili.com/video/BV1Tx411o7rH/?vd_source=fcddcf87e97b17fd530dc88db643aab3 关于catkin_ws这种ROS的工作环境的配置,具体可以参考我的这篇博客 https://www.cnblogs.com/myleaf/p/1…

SpringMVC 学习笔记

概述 SpringMVC 中的 MVC 即模型-视图-控制器,该框架围绕一个 DispatcherServlet 改计而成,DispatcherServlet 会把请求分发给各个处理器,并支持可配置的处理器映射和视图渲染等功能 SpringMVC 的工作流程如下所示:客户端发起 HTTP 请求:客户端将请求提交到 DispatcherSer…

VMware vSphere 6.7 Update 3w 下载

VMware vSphere 6.7 Update 3w 下载VMware vSphere 6.7 Update 3w 下载 ESXi 6.7 U3 & vCenter Server 6.7 U3, Dell, HPE, LENOVO, Inspur Custom Image 请访问原文链接:https://sysin.org/blog/vmware-vsphere-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sys…

HER304-ASEMI轴向高效恢复二极管HER304

HER304-ASEMI轴向高效恢复二极管HER304编辑:ll HER304-ASEMI轴向高效恢复二极管HER304 型号:HER304 品牌:ASEMI 封装:DO-27 特性:轴向高效恢复二极管 正向电流:3A 反向耐压:300V 恢复时间:35ns 引脚数量:2 芯片个数:2 芯片尺寸:MIL 浪涌电流:125A 漏电流:10ua 工作…