面向对象->实验报告一(C++)

实验任务三


题目要求

面向对象->实验报告一(C++)

根据实验要求,有一个成员函数为add,同时又有一个友元函数add,这两个用法和意义是不同的,需要注意。


main.cpp

#include <iostream>
#include "func.hpp"
using namespace std;
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;
}

func.hpp

#ifndef CPP_FUNC_HPP
#define CPP_FUNC_HPP

#include "iostream"
#include "cmath"
class Complex{
    double real, imag;
public:
    Complex(){};
    Complex(double _real, double _imag = 0):real(_real), imag(_imag){};
    Complex(const Complex &_temp){
        real = _temp.real;
        imag = _temp.imag;
    };
    double get_real() const{
        return real;
    }
    double get_imag() const{
        return imag;
    }
    void show() const{
        if (imag > 0)
            std::cout << get_real() << " + " << get_imag() << "i";
        else if (imag < 0)
            std::cout << get_real() << " - " << (-1) * get_imag() << "i";
        else
            std::cout << get_real();
    }
    void add(Complex x);
  	// 注意const
    friend Complex add(const Complex &x, const Complex &y);
    friend bool is_equal(const Complex &x, const Complex &y);
    friend double abs(Complex &x);
};

void Complex::add(Complex x) {
    imag += x.get_imag();
    real += x.get_real();
}
Complex add(const Complex &x, const Complex &y){
    Complex temp;
    temp.real = x.get_real() + y.get_real();
    temp.imag = x.get_imag() + y.get_imag();
    return temp;
}
bool is_equal(const Complex &x, const Complex &y){
    if(x.get_imag() == y.get_imag() && x.get_real() == y.get_real())return true;
    else
        return false;
}
double abs(Complex &x){
    double value;
    value = sqrt(x.imag * x.imag + x.real * x.real);
    return value;
}

#endif //CPP_FUNC_HPP
面向对象->实验报告一(C++)面向对象->实验报告一(C++)

实验任务四


题目

面向对象->实验报告一(C++)

整体观察,要完成以上基本功能是没有一个部分有难度的。但对于密码、邮箱的审查是需要了解一定的正则表达式的基础的(下面代码中会有体现)。另外,由于是c++的缘故,对于密码的加密存储(不仅是后端数据库,更是源文件本身)是比较复杂的。如果后端是php则应在前端向后端传输的过程中就进行md5等非对称hash加密,以确保数据的安全。另外,对于密码也应有严格的审查(例如最小位数、特殊字符、大小写、数字等),而在这里给出的源码只是对其进行了基础的位数验证,同样利用正则表达式是可以达到这样的效果的。对邮箱的验证是比较严格的,对于邮箱后缀进行了字典式匹配,仅支持几种常见的邮箱服务商。


main.cpp

#include "func.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();
}

func.hpp

#ifndef CPP_FUNC_HPP
#define CPP_FUNC_HPP

#include <iostream>
#include <regex>
#include <ctime>
class User{
    std::string name, passwd, email;
    static int n;
public:
    User(std::string _name, std::string _passwd="111111", std::string _email=""):name(_name), passwd(_passwd), email(_email){
        n++;
    };
    void set_email();
    void change_passwd();
    void print_info() const{
        std::cout << "name:\t" << name << std::endl;
        std::cout << "passwd:\t" << "******" << std::endl;
        std::cout << "email:\t" << email << std::endl;
    }
    static void print_n(){
        std::cout << "there are " << n << " users";
    }
};
// 记录对象数
int User::n = 0;
void User::set_email(){
    std::string _email;
    int times = 3;
    while(times--){
        std::cout << "Enter email address: ";
        std::cin >> _email;
        // 正则匹配,对邮箱合法性进行判断
        bool value = regex_match(_email, std::regex("\\w+?@(qq|gmail|163|126|yahoo|msn|hotmail|live)\\.(com|net|cn)"));
        if (value && _email != email)
        {
            email = _email;
            std::cout << "email is set successfully..." << std::endl;
            break;
        }
        else
        {
            if(!times) std::cout << "Incorrect email format. Please try after a while." << std::endl;
            std::cout << "Incorrect email format.";
        }
    }
}

void User::change_passwd(){
    std::string _tempass;
    int times = 3, time = 3;
    std::cout << "Enter old password: ";
    while(times--){
        std::cin >> _tempass;
        // 验证通过。修改密码
        if(_tempass == passwd){
            while(time--){
                std::cout << "Enter new passwd:" ;
                std::cin >> _tempass;
                // 正则匹配,密码长度需大于等于6位
                bool value = regex_match(_tempass, std::regex(".{6}.*"));
                // 且不能和旧密码相同
                if (value && _tempass != passwd){
                    passwd = _tempass;
                    std::cout << "new passwd is set successfully..." << std::endl;
                    break;
                }
                else
                    std::cout << "your passwd is too simple!" << std::endl;
            }
            if(!time)break;
        }
        // 旧密码错误
        else{
            if (times == 0) {
                std::cout << "password input error. Please try after a while." << std::endl;
                break;
            }
            else std::cout << "password input error. Please re-enter again: ";
        }
    }
}

#endif //CPP_FUNC_HPP

面向对象->实验报告一(C++)



总结

  • 对于代码的安全性应时刻注意,权限的细分、最小化原则。
  • 数据存储的安全性很重要。从源码开始就应该进行非对称加密。
  • 接口的完备性是常常缺乏考虑的一点,一个成熟的接口应具备应对各种输入并进行合理的反馈。如存在漏洞则会变得非常危险。
  • 友元函数的定义和适用范围、条件等需要明确,
上一篇:MySQL数据库查询速度优化之解决技巧


下一篇:重学C++(二)