面向對象->實驗報告一(C++)


實驗任務三

歡迎訪問我的個人博客:

xzajyjs.cn


題目要求

根據實驗要求,有一個成員函數為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++的緣故,對於密碼的加密存儲(不僅是后端數據庫,更是源文件本身)是比較復雜的。如果后端是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>
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;
            }
            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



總結

  • 對於代碼的安全性應時刻注意,權限的細分、最小化原則。
  • 數據存儲的安全性很重要。從源碼開始就應該進行非對稱加密。
  • 正則表達式在實際場景中有着廣泛的應用。
  • 接口的完備性是常常缺乏考慮的一點,一個成熟的接口應具備應對各種輸入並進行合理的反饋。如存在漏洞則會變得非常危險。
  • 友元函數的定義和適用范圍、條件等需要明確,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM