实验2 类和对象(2)

实验目的

  1. 能够使用C++语法规则正确定义、实现、测试类。
  2. 能够使用C++语法规则正确创建对象,并基于对象编程。
  3. 知道类的static成员用于解决什么问题场景,会正确使用c++语法规则实现和访问static成员。
  4. 知道友元机制用于解决什么问题场景,会正确使用c++语法规则实现和使用友元函数、友元类。
  5. 知道const限定对象、引用、类成员用于解决什么问题场景,能正确、合理使用。
  6. 对于规模较大的程序,会用多文件方式组织代码。
  7. 体会面向对象编程在解决问题时的思维方式。

实验内容

4. 实验任务4

实验代码

Complex.hpp

#pragma once

#include<iostream>
#include<cmath>
using namespace std;

class Complex
{
private: 
	double real, imag;
public:
    Complex(double r=0, double i=0):real{r},imag{i}{};
    Complex(Complex &c){real=c.real;imag=c.imag;}
    double get_real()const{return real;}
    double get_imag()const{return imag;}
    void show() const;
    void add(const Complex &);
    friend Complex add(const Complex &,const Complex &);
    friend bool is_equal(const Complex &,const Complex &);
    friend double abs(Complex &);
};

void Complex::show() const{
    if(imag>0){
        cout<<real<<" "<<"+ "<<abs(imag)<<"i";
    }else if(imag<0){
        cout<<real<<" "<<"- "<<abs(imag)<<"i";
    }else{
        cout<<real;
    }
}

void Complex::add(const Complex &c) { 
	real+=c.get_real();
    imag+=c.get_imag();
}

Complex add(const Complex &c1,const Complex &c2){
    Complex c;
    c.real=c1.real+c2.real;
    c.imag=c1.imag+c2.imag;
    return c;
}

bool is_equal(const Complex &c1,const Complex &c2){
    return (c1.real==c2.real)&&(c1.imag==c2.imag);
}

double abs(Complex &c){
    return sqrt(pow(c.real,2)+pow(c.imag,2));
}

task4.cpp

#include "Complex.hpp"
#include <iostream>

// 类测试
void test() {
    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;
}

int main() {
    test();
    return 0;
}

测试结果

test4

5.实验任务5

实验代码

User.hpp

#pragma once

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class User
{
private:
    string name, passwd, email;
    static int n;

public:
    User(string name0, string passwd0="111111", string email0="") : name{name0}, passwd{passwd0}, email{email0} { n++; }
    void set_email();
    void change_passwd();
    void print_info();
    void static print_n();
};
int User::n = 0;
void User::set_email()
{
    string newEmail;
    cout << "Enter email address: ";
    cin >> newEmail;
    email = newEmail;
    cout << "email is set successfully..." << endl;
}

void User::change_passwd()
{
    string newPasswd,oldPasswd;
    int wrongTime;
    cout << "Enter old password: ";
    cin >> oldPasswd;
    while (wrongTime <2 )
    {
        if (passwd == oldPasswd)
        {
            cout << "Enter new password: ";
            cin >> newPasswd;
            passwd = newPasswd;
            cout << "new passwd is set successfully..." << endl;
            break;
        }
        else
        {
            wrongTime++;
            cout << "password input error. Please re-enter again: ";
            cin >> oldPasswd;
        }
    }
    if (wrongTime ==2 )
    {
        cout << "password input error. Please try after a while." << endl;
    }
}

void User::print_info()
{
    string starPasswd(passwd.length(), '*');
    cout << setfill(' ') << setw(8) << left <<"name:"<< name << endl
         << setfill(' ') << setw(8) << left <<"passwd:"<< starPasswd << endl
         << setfill(' ') << setw(8) << left <<"email:"<< email << endl;
}

void User::print_n()
{
    cout <<"there are "<< n <<" users."<< endl;
}

task5.cpp

#include "User.hpp"
#include <iostream>

// 测试User类
void test() {
    using std::cout;
    using std::endl;

    cout << "testing 1......\n";
    User user1("Jonny", "92197", "xyz@hotmail.com");
    user1.print_info();

    cout << endl
         << "testing 2......\n\n";
         
    User user2("Leonard");
    user2.change_passwd();
    user2.set_email();
    user2.print_info();

    cout << endl;
    User::print_n();
}

int main() {
    test();
    return 0;
}

测试结果

test5.1


test5.2

1. 实验任务1

实验代码

#include <iostream>
#include <complex>

int main(int argc, char const *argv[]){
    using namespace std;

    complex<double> c1{3, 4}, c2{4.5};
    const complex<double> c3{c2};

    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << c2 << endl;
    cout << "c3 = " << c3 << endl;
    cout << "c3.real = " << c3.real() << endl;
    cout << "c3.imag = " << c3.imag() << endl;

    cout << "c1 + c2 = " << c1 + c2 << endl;
    cout << "c1 - c2 = " << c1 - c2 << endl;
    cout << "abs(c1) = " << abs(c1) << endl; // abs()是标准库中数学函数,对复数进行取模    

    cout << boolalpha;  // 设置bool型值以true/false方式输出
    cout << "c1 == c2 : " << (c1 == c2) << endl;
    cout << "c3 == c2 : " << (c3 == c2) << endl;
    
    complex<double> c4 = 2;
    cout << "c4 = " << c4 << endl;
    c4 += c1;
    cout << "c4 = " << c4 << endl;
    return 0;
}

测试结果

test1

2. 实验任务2

实验代码

#include <iostream>
#include <array>
#include <string>

// 模板函数
// 对满足特定条件的序列类型T,使用范围for输出
template<typename T>
void output1(const T &obj) {
    for(auto i: obj)
        std::cout << i << ", ";
    std::cout << "\b\b \n";
}

// 模板函数
// 对满足特定条件的序列类型T,使用迭代器输出
template<typename T>
void output2(const T &obj) {
    for(auto p = obj.cbegin(); p != obj.cend(); ++p) //使用const迭代器
        std::cout << *p << ", ";
    std::cout << "\b\b \n";
}

int main(int argc, char const *argv[]) {
    using namespace std;

    array<int, 5> x1; // 创建一个array对象,包含5个int类型元素,未初始化
    cout << "x1.size() = " << x1.size() << endl; // 输出元素个数
    x1.fill(42); // 将x1的所有元素值都赋值为42
    x1.at(0) = 999;  // 把下标为0的元素修改为999
    x1.at(4) = -999; // 把下标为4的元素修改为-999
    x1[1] = 777; // 把下标为1的元素修改为777
    cout << "x1: ";
    output1(x1);
    cout << "x1: ";
    output2(x1);

    array<double, 10> x2{1.5, 2.2}; // 创建要给array对象,包含10个double类型元素,初始化部分元素
    cout << "x2.size() = " << x2.size() << endl;
    cout << "x2: ";
    output1(x2);

    array<int, 5> x3{x1};
    cout << boolalpha << (x1 == x3) << endl;
    x3.fill(22);
    cout << "x3: ";
    output1(x3);

    swap(x1, x3); // 交换x1和x3的数据
    cout << "x1: ";
    output1(x1);
    cout << "x3: ";
    output1(x3);
    return 0;
}

测试结果

test2

3. 实验任务3

实验代码

Employee.hpp

#pragma once

// Employee类的定义
#include <iostream>
#include <string>
#include <iomanip>

using std::string;
using std::cout;
using std::endl;
using std::setfill;
using std::setw;
using std::left;
using std::to_string;

struct Date {
    int year;
    int month;
    int day;
};

// Employee类的声明
class Employee
{
public:
    Employee();
    Employee(string name0, double salary0, int y, int m, int d = 1);
    void set_info(string name0, double salary0, int y, int m, int d = 1); // 设置雇员信息
    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);  // 计算提薪加成

public:
    static void display_count();    // 类方法,显示雇员总数

private:
    string id;     // 雇员工号
    string name;   // 雇员姓名
    double salary; // 雇员薪水
    Date hire_date;  // 雇员雇佣日期

public:
    static const string doc;  // 类属性,用于描述类

private:
    static int count;   // 类属性,用于记录雇员总人数

};

const string Employee::doc {"a simple Employee class"};
int Employee::count = 0;

// 默认构造函数
Employee::Employee(): id{ to_string(count+1) } {
    ++count;
}

// 带参数的构造函数
Employee::Employee(string name0, double salary0, int y, int m, int d): 
          id{to_string(count+1)}, 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 << left << setw(15) << "id: " << id << endl;
    cout << setw(15) << "name: " << name << endl;
    cout << setw(15) << "salary: " << salary << endl;
    cout << setw(15) << "hire_date: " << hire_date.year << "-";
    cout << std::right << setfill('0') << setw(2) << hire_date.month << "-"  << setw(2) << hire_date.day;
    cout << setfill(' ');  // 恢复到默认空格填充
}

// 更新薪水
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";
}

test3.cpp

#include "Employee.hpp"
#include <iostream>

void test() {
    using std::cout;
    using std::endl;

    cout << Employee::doc << endl << endl;

    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); // 提成15%
    employee2.display_info();
    cout << endl << endl;

    Employee::display_count();
}

int main(int argc, char const *argv[]) {
    test();
    return 0;
}

测试结果

test3

posted @ 2022-10-12 19:25  水孔蛋白  阅读(71)  评论(0编辑  收藏  举报