首页 > 其他分享 >实验二 类与对象

实验二 类与对象

时间:2022-10-17 20:00:25浏览次数:48  
标签:std const 对象 double void int Complex 实验

实验任务一

#include <iostream>
#include <complex>

int main(){
    using namespace std;

    complex<double> c1{3, 4}, c2{4.5};//支持两个参数//使用时,在语法层面需要通过<>指定具体类型(即特化到特定类型)
    const complex<double> c3{c2};//也支持一个参数(默认虚部为0)

    cout << "c1 = " << c1 << endl;//支持使用标准数据流对象cout和插入运算符<<直接输出复数类型
    cout << "c2 = " << c2 << endl;
    cout << "c3 = " << c3 << endl;
    cout << "c3.real = " << c3.real() << endl;//comple模板类提供有接口,返回复数的实部和虚部
    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;//把一个int类型的常数,转换为复数类型
    cout << "c4 = " << c4 << endl;
    c4 += c1;//支持复合赋值运算
    cout << "c4 = " << c4 << endl;
}

使用类的非成员函数abs()可以对复数进行取模运算。设复数的实部和虚部分别是real和
imag, 取模运算规则:sqrt(real2+imag2)


实验任务二

#include <iostream>
#include <array>
#include <string>
using namespace std;

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

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

int main() {
    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
//xx.at(i) 访问索引为i的元素。相较于xx[i]这种方式,使用xx.at(i)会做越界检查,更安全。
    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);
}

说明:

  1. array 是一个大小固定的容器模板类。使用时,需要将指定容器大小和元素类型。
  2. xx.size() 返回容器数据项个数。
  3. xx.fill(value) 将array内所有元素用value填充。
  4. swap(xx, xx) 交换两个array元素值。
  5. xx.at(i) 访问索引为i的元素。相较于xx[i]这种方式,使用xx.at(i)会做越界检查,更安全。
  6. xx.cbegin() , xx.cend() 也是容器类的迭代器,和实验1文档中中的 xx.begin() , x.end() 相比,c表示const,所以,通过这一组迭代器访问时,不能通过迭代器修改容器类元素的值。类似地,还有 xx.crbegin() , xx.crend()

  1. 相较于C风格的数组,array提供了更安全的访问方式,同时,也扩充了一些操作。
  2. 相较于vector,array功能不如vector丰富、灵活,但对于大小固定的应用场景,array具备更高效的性能。
  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::right;
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";
}

task.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() {
    test();
}

说明:

  1. 这个简单编程示例采用多文件结构组织代码,Employee类的定义和实现单独放在文件employee.hpp中。类的测试代码放在task3.cpp中。
  2. Employee类中使用到了这些C++语言特性:构造函数、类的static成员、const成员函数、带有默认值的函数。
  3. 在显示员工信息成员函数 display_info() 中,使用了一部分操控符函数,控制数据输出格式。
  4. 在文件employee.hpp中, #pragma once 指令用于保证文件不会被重复包含,标识符不会被重复引用。也可以使用 #ifndef xxx #define xxx #endif 实现同等效果。

实验任务四

complex.h

#pragma once

#include <iostream>
#include<complex>

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

}
Complex add(Complex c1, Complex c2) {
	Complex c3;
	c3.real = c1.real + c2.real;
	c3.img = c1.img + c2.img;
	return c3;
}
bool is_equal(Complex c1, Complex c2)
{
	if (c1.img == c2.img && c1.real == c2.real)
		return 1;
	else
		return 0;
}
double abs(Complex c)
{
	double count = 0;
	count = sqrt(c.img * c.img + c.real * c.real);
	return count;
}

void Complex::show()const {
	if (img > 0)
		std::cout << real << "+" << img << "i" << std::endl;
	else if (img < 0)
		std::cout << real << img << "i" << std::endl;
	else if (img == 0)
		std::cout << real << std::endl;
}

task.cpp

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

// 类测试
void test() {
    using namespace std;

    Complex c1(5, -2);
    const Complex c2(7.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();
}

image


实验任务五

user.h

#pragma once

#include<iostream>;
#include<string>

class User {
public:
	User(std::string name0, std::string password0 = "111111", std::string email0 = "");
	void set_email();
	void change_passwd();
	void print_info();
	void static print_n() {
		std::cout << "共有 " << n << " 名用户" << std::endl;
	}
private:
	std::string name;
	std::string email;
	std::string passwd;
	static int n;
};

int	User::n = 0;
User::User(std::string name0, std::string password0, std::string email0) :name{ name0 }, email{ email0 }, passwd{ password0 } { n++; }

void User::set_email() {
	std::string email1;
	std::cout << "请用户用键盘输入邮箱地址!" << std::endl;
	std::cin >> email1;
	if (email1 != "")
	{
		email = email1;
		std::cout << "邮箱设置成功!" << std::endl;
	}
	else
		std::cout << "未设置邮箱,将使用默认值!" << std::endl;
}

void User::change_passwd() {
	std::cout << "请输入旧密码!" << std::endl;
	std::string password;
	for (int i = 0; i < 3; i++)
	{
	flag:
		std::cin >> password;
		if (password != passwd)
		{
			std::cout << "原密码不正确,请重新输入!";
			std::cout << "已连续输入错误" << i + 1 << "次!" << std::endl;
			if (i == 2)
			{
				std::cout << "已连续输入三次错误密码,请稍后再试。" << std::endl;
				goto flag;
			}

		}
		else if (password == passwd)
		{
			std::cout << "原密码验证成功,请输入新密码!" << std::endl;
			std::cin >> passwd;
			std::cout << "密码修改成功!" << std::endl;
			break;
		}
	}
}

void User::print_info() {
	int length = passwd.length();
	std::cout << "用户名为:" << name << std::endl;
	std::cout << "邮箱为:" << email << std::endl;
	std::cout << "密码为:";
	while (length--)
	{
		std::cout << "*";
		if (length == 0)
			std::cout << std::endl;
	}
}

taks5.cpp

#include "User.hpp"
#include <iostream>
// 测试User类
void test() {
	using std::cout;
	using std::endl;
	cout << "testing 1......\n";
	User user1("Li", "123456", "[email protected]");
	user1.print_info();
	cout << endl
		<< "testing 2......\n\n";
	User user2("lixuan");
	user2.change_passwd();
	user2.set_email();
	user2.print_info();
	cout << endl;
	User::print_n();
}
int main() {
	test();
	}

image


标签:std,const,对象,double,void,int,Complex,实验
From: https://www.cnblogs.com/Cali-AKA/p/16785273.html

相关文章