C++ 实验一 任务报告
📝实验一 任务报告
✨实验总结
😟遇到的问题:
略.
🧐解决方法:
略.
🤔思考:
略.
✨实验内容
🕐任务一
验证性实验。
使用C++标准库提供的复数模板类complex编码实现简单的复数运算。
在C++编码环境中,输入以下代码,结合运行结果,体验使用C++标准库进行编程的便捷,同时,观察和 理解类、对象、库函数的使用。
📃代码:
#include <complex.h>
#include <iostream>
#include <cmath>
int main()
{
using namespace std;
complex<double> c1(3, 4);
complex<double> c2(4.5);
complex<double> c3(c2);
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;
cout << "c3 = " << c3 << endl;
cout << "c1 + c2 = " << c1 + c2 << endl;
cout << boolalpha; // 设置bool型值以true/false方式输出
cout << "c1 == c2 : " << (c1 == c2) << endl;
cout << "c3 == c2 : " << (c3 == c2) << endl;
cout << "abs(c1) = " << abs(c1) << endl; // abs()对复数进行取模运算,头文件cmath
complex<int> c4(3, 4), c5(2, 7);
cout << "c4 - c5 = " << c4 - c5 << endl;
}
🎨截图:
🤓思考:
(1) 复数模板类complex
。由于是模板类,是对于抽象的数据类型,所以,使用时,在语法层面通过<>
指 定具体类型。比如,分别指定复数类的实部和虚部是double
类型和int
类型。
(2) 库函数abs()
。对于复数类型,abs()
实现的是取模运算。设复数的实部和虚部分别是real
和imag
, 取模 运算规则:sqrt(real2+imag2)
🕑任务二
验证性实验。
设计并实现一个雇员类Employee
,满足如下要求:
数据成员
包括员工姓名、薪水、雇佣日期,以及,员工总数
函数成员
包括构造函数、设置员工信息、更新员工信息(薪水、雇佣时间)、打印员工信息、打印员工总数 等。
其中,Employee
类定义在文件Employee.hpp
中,使用类Employee
类的测试代码在文件task2.cpp
中。
在C++
编码环境中,输入以下代码,结合运行结果,理解和巩固C++
中类的定义、实现方法,及const
成员、static
成员等。
📃代码:
task2.hpp
#ifndef EMPLOYEE_HPP
#define EMPLOYEE_HPP
// Employee类的定义
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
struct Date
{
int year;
int month;
int day;
};
// Employee类的声明
class Employee
{
public:
Employee();
Employee(string name0, double salary0, int y, int m, int d);
void set_info(string name0, double salary0, int y, int m, int d); // 设置雇员信息
string get_name() const; // 获取雇员姓名
double get_salary() const; // 获取雇员薪水
void display_info() const; // 显示雇员信息
void update_salary(double s); // 更新雇员薪水
void update_hire_date(int y, int m, int d); // 更新雇佣日期
void raise_salary(double by_percent); //
static void display_count();
private:
string name; // 雇员姓名
double salary; // 雇员薪水
Date hire_date; // 雇员雇佣日期
static int count; // 用于记录雇员总人数
};
int Employee::count = 0;
// 默认构造函数
Employee::Employee()
{
++count;
}
// 带参数的构造函数
Employee::Employee(string name0, double salary0, int y, int m, int d) :
name{name0}, salary{salary0}, hire_date{y, m, d}
{
++count;
}
// 设置员工信息
void Employee::set_info(string name0, double salary0, int y, int m, int d)
{
name = name0;
salary = salary0;
hire_date.year = y;
hire_date.month = m;
hire_date.day = d;
}
// 获取员工姓名
string Employee::get_name() const
{
return name;
}
// 获取员工薪水
double Employee::get_salary() const
{
return salary;
}
// 显示雇员信息
void Employee::display_info() const
{
cout << "name: " << name << endl;
cout << "salary: " << salary << endl;
cout << "hire_date: " << hire_date.year << "-" << setfill('0') <<
setw(2) << hire_date.month << "-"
<<
setw(2) << hire_date.day;
}
// 更新薪水
void Employee::update_salary(double s)
{
salary = s;
}
// 更新雇佣日期
void Employee::update_hire_date(int y, int m, int d)
{
hire_date.year = y;
hire_date.month = m;
hire_date.day = d;
}
// 雇员提薪加成
// by_percent是提升比例
void Employee::raise_salary(double by_percent)
{
double raise = salary * by_percent / 100;
salary += raise;
}
// 显示雇员总数
void Employee::display_count()
{
cout << "there are " << count << " employees\n";
}
#endif
task2.cpp
#include "task2.hpp"
#include <iostream>
int main()
{
using namespace std;
Employee employee1;
employee1.set_info("Sam", 30000, 2015, 1, 6);
employee1.update_hire_date(2017, 6, 30);
employee1.update_salary(35000);
employee1.display_info();
cout << endl << endl;
Employee employee2("Tony", 20000, 2020, 3, 16);
employee2.raise_salary(15);
employee2.display_info();
cout << endl << endl;
Employee::display_count();
return 0;
}
🎨截图:
🤓思考:
略.
🕒任务三
不使用C++
标准库,自行设计并实现一个复数类Complex
,使其满足如下要求:
数据成员
用来表示复数的实部real
和虚部imag
,实部、虚部,均为小数形式。
函数成员
构造函数 支持以下方式定义复数对象:
Complex c1; // 不带参数
Complex c2(3); // 只有一个参数,相当于3 + 0i
Complex c3(3, 4); // 两个参数,相当于3 + 4i
Complex c4(c3); // 用c3构造c4
成员函数
-
get_real()
返回复数实部 -
get_imag()
返回复数虚部 -
show()
用于输出复数。要求以3 + 4i
,3 - 4i
这样的形式输出add()
用于把一个复数加到自身,比如c1.add(c2)
,相当于c1 += c2
友元函数
-
add()
用于实现两个复数相加,返回复数。比如c3 = add(c1, c2);
is_equal()
用于判断两个复数是否相等,返回true/false
。比如is_equal(c1, c2)
-
abs()
用于对复数进行取模运算 将类Complex
的定义及友元函数实现,单独保存在文件Complex.hpp
中。
使用task3.cpp
中的代码,测试类Complex
的各项接口是否正确。
📃代码:
task3.hpp
#ifndef TASK3_HPP
#define TASK3_HPP
#include <iostream>
#include <cmath>
using namespace std;
class Complex
{
private:
double a;
double b;
public:
Complex() : a(0), b(0) {}
Complex(double num1, double num2 = 0) : a(num1), b(num2) {}
Complex(const Complex &c) : a(c.a), b(c.b) {}
friend Complex add(const Complex &c1, const Complex &c2);
friend bool is_equal(const Complex &c1, const Complex &c2);
friend double abs(const Complex &c1);
double get_real() const { return a; }
double get_imag() const { return b; }
void show() const
{
if (!b)
cout << a << endl;
else
cout << a << " " << (signed int) b << "i" << endl;
}
void add(const Complex &c2)
{
a += c2.a;
b += c2.b;
}
};
Complex add(const Complex &c1, const Complex &c2)
{
Complex c3(c1.a + c2.a, c1.b + c2.b);
return c3;
}
bool is_equal(const Complex &c1, const Complex &c2)
{
if (c1.get_imag() == c2.get_imag() && c1.get_real() == c2.get_real())
return true;
else
return false;
}
double abs(const Complex &c1)
{
return sqrt((c1.a * c1.a) + (c1.b * c1.b));
}
#endif //TASK3_HPP
task3.cpp
#include "task3.hpp"
#include <iostream>
int main()
{
using namespace std;
Complex c1(3, -4);
const Complex c2(4.5);
Complex c3(c1);
cout << "c1 = ";
c1.show();
cout << endl;
cout << "c2 = ";
c2.show();
cout << endl;
cout << "c2.imag = " << c2.get_imag() << endl;
cout << "c3 = ";
c3.show();
cout << endl;
cout << "abs(c1) = ";
cout << abs(c1) << endl;
cout << boolalpha;
cout << "c1 == c3 : " << is_equal(c1, c3) << endl;
cout << "c1 == c2 : " << is_equal(c1, c2) << endl;
Complex c4;
c4 = add(c1, c2);
cout << "c4 = c1 + c2 = ";
c4.show();
cout << endl;
c1.add(c2);
cout << "c1 += c2, " << "c1 = ";
c1.show();
cout << endl;
return 0;
}
🎨截图:
🤓思考:
复习了一下条件运算符(?:
)
【友元函数
】在类内部,只能申明函数原型,不能定义函数体,不受访问级别的限制。
【友元类
】友类的每个成员都可以访问另一个类中的保护成员和私有成员。
🕓任务四
设计并实现一个用户类User
,并在主函数中使用和测试这个类。具体要求如下:
数据成员
每个用户有用户名name
、密码passwd
、联系邮箱email
三个属性。
还有一个类属性,用于记录用户总数n
。
函数成员
构造函数 如果定义用户对象时未设置密码和邮箱,密码默认为6个1
,联系邮箱默认为空串。
User u1("Mary"); // 密码和邮箱,使用默认设置
User u2("John", "112233", "xyz@gmail.com")
成员函数
-
set_email()
设置邮箱。提示用户从键盘输入邮箱。 -
change_passwd()
修改密码。修改密码前,要求先输入旧的密码,验证无误后,才允许修改;如果输入旧 密码时,连续三次输入错误,则提示用户稍后再试,暂时退出修改密码程序。 -
print_info()
打印用户名、密码、联系邮箱。其中,密码以6个*
方式显示。
User
类的定义和实现,保存在文件User.hpp
中。 User
类的使用和测试,保存在文件task4.cpp
中。
📃代码:
task4.hpp
#ifndef TASK4_HPP
#define TASK4_HPP
#include <iostream>
#include <string>
using namespace std;
class User
{
private:
string name;
string passwd;
string email;
public:
static int num;
User(string n = "Default", string p = "111111", string e = "") : name(n), passwd(p), email(e) { num++; }
static void print_n() { cout << "Num of users is: " << num; }
void print_info() { cout << "Name:" << name << " Passwd:" << "******" << " E-mail:" << email << endl; }
void set_email()
{
cout << "Please enter your E-mail:";
cin >> email;
cout << "Setting E-mail... Done." << endl;
}
void change_passwd()
{
string temp, new_passwd;
cout << "Changing password for " << name << endl;
cout << "Old password:";
cin >> temp;
if (passwd != temp)
{
cout << "Wrong password, please try again." << endl;
}
else
{
cout << "New password:";
cin >> temp;
cout << "Ensure password:";
cin >> new_passwd;
if (temp != new_passwd)
cout << "New password doesn't match, please try again." << endl;
else
{
passwd = new_passwd;
cout << "Changing password... Done." << endl;
}
}
}
};
int User::num = 0;
#endif //TASK4_HPP
task4.cpp
#include "task4.hpp"
#include <iostream>
int main()
{
using namespace std;
cout << "testing 1......" << endl;
User user1("Jonny", "92197", "xyz@hotmail.com");
user1.print_info();
cout << endl
<< "testing 2......" << endl
<< endl;
User user2("Leonard");
user2.change_passwd();
user2.set_email();
user2.print_info();
User::print_n();
}
🎨截图:
🤓思考:
User
类的完善及拓展丰富*(选做)
-
设置邮箱时,对邮箱地址合法性进行检测提示,比如,是否包含@
-
设置密码时,对密码的长度、合法性进行校验
使用正则表达式匹配,如果合法则修改密码或邮箱
#ifndef TASK4_HPP
#define TASK4_HPP
#include <iostream>
#include <string>
#include <regex>
using namespace std;
class User
{
private:
string name;
string passwd;
string email;
public:
static int num;
User(string n = "Default", string p = "111111", string e = "") : name(n), passwd(p), email(e) { num++; }
void change_passwd();
void set_email();
static void print_n() { cout << "Num of users is: " << num; }
void print_info() const { cout << "Name:" << name << " Passwd:" << "******" << " E-mail:" << email << endl; }
};
int User::num = 0;
void User::change_passwd()
{
string temp, new_passwd, str;
cout << "Changing password for " << name << endl;
cout << "Old password:";
cin >> temp;
if (passwd != temp)
{
cout << "Wrong password, please try it again." << endl;
}
else
{
cout << "New password:";
cin >> temp;
cout << "Ensure password:";
cin >> new_passwd;
if (temp != new_passwd)
cout << "New password doesn't match, please try it again." << endl;
else
{
//密码规则:长度>=8,包含大小写和特殊字符
if (new_passwd.length() >= 8 && regex_search(new_passwd, regex("\\d")) &&
regex_search(new_passwd, regex("\\W")) && regex_search(new_passwd, regex("[a-z]")) &&
regex_search(new_passwd, regex("[A-Z]")))
{
passwd = new_passwd;
cout << "Changing password... Done." << endl;
}
else
cout
<< "Must be 8 characters or more;" << endl
<< "Needs at least one number,one uppercase letter, one lowercase letter and one symbol."
<< endl
<< "Change password failed." << endl;
}
}
}
void User::set_email()
{
string str, temp = email;
cout << "Please enter your E-mail:";
cin >> email;
//邮箱规则: 依次包含`@`和`.`
if (regex_match(email, regex(".+[@].+[.].+")))
cout << "Setting E-mail... Done." << endl;
else
{
email = temp;
cout << "Invalid E-mail. Set E-mail failed." << endl;
}
}
#endif //TASK4_HPP