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