C++之純虛函數和抽象類

純虛函數和抽象類

1.基本概念

這里寫圖片描述
這里寫圖片描述
這里寫圖片描述

2.案例

#include <iostream>
using namespace std;////面向抽象類編程(面向一套預先定義好的接口編程)//解耦合 ....模塊的劃分class  Figure //抽象類
{
public://閱讀一個統一的界面(接口),讓子類使用,讓子類必須去實現virtual void getArea() = 0 ; //純虛函數
protected:
private:
};class Circle : public Figure
{
public:Circle(int a, int b){this->a = a;this->b = b;}virtual void getArea(){cout<<"圓形的面積: "<<3.14*a*a<<endl;;}private:int a;int b;
};class Tri : public Figure
{
public:Tri(int a, int b){this->a = a;this->b = b;}virtual void getArea() {cout<<"三角形的面積: "<<a*b/2<<endl;;}private:int a;int b;
};class Square : public Figure
{
public:Square(int a, int b){this->a = a;this->b = b;}virtual void getArea() {cout<<"四邊形的面積: "<<a*b<<endl;;}private:int a;int b;
};void objplay(Figure *base)
{base->getArea(); //會發生多態
}void main511()
{//Figure f; //抽象類不能被實例化Figure *base = NULL; //抽象類不能被實例化Circle c1(10, 20);Tri t1(20, 30);Square s1(50, 60);//面向抽象類編程(面向一套預先定義好的接口編程)objplay(&c1);objplay(&t1);objplay(&s1);//c1.getArea();cout<<"hello..."<<endl;system("pause");return ;
}

3.抽象類在多繼承中的應用

C++中沒有Java中的接口概念,抽象類可以模擬Java中的接口類。(接口和協議)

  • 工程上的多繼承

    • 被實際開發經驗拋棄的多繼承
    • 工程開發中真正意義上的多繼承是幾乎不被使用的
    • 多重繼承帶來的代碼復雜性遠多于其帶來的便利
    • 多重繼承對代碼維護性上的影響是災難性的
    • 在設計方法上,任何多繼承都可以用單繼承代替
  • 多繼承中的二義性和多繼承不能解決的問題
    這里寫圖片描述

  • C++沒有接口只有多繼承和抽象類

    • 絕大多數面向對象語言都不支持多繼承
    • 絕大多數面向對象語言都支持接口的概念
    • C++中沒有接口的概念
    • C++中可以使用純虛函數實現接口
    • 接口類中只有函數原型定(純虛函數)義,沒有任何數據的定義。
class Interface
{public:virtual void func1() = 0;virtual void func2(int i) = 0;virtual void func3(int i) = 0; 
};
  • 實際工程經驗證明

    • 多重繼承接口不會帶來二義性和復雜性等問題
    • 多重繼承可以通過精心設計用單繼承和接口來代替
    • 接口類只是一個功能說明,而不是功能實現。
    • 子類需要根據功能說明定義功能實現。
  • 多繼承的二義性

#include <iostream>
using namespace std;class  B
{
public:int b;
protected:
private:
};class  B1 : virtual public B
{
public:int b1;
protected:
private:
};class  B2 : virtual public B
{
public:int b2;
protected:
private:
};class  C : public B1, public B2
{
public:int c;
protected:
private:
};void main61()
{C myc;myc.c = 10;myc.b = 100;//二義性  error C2385: 對“b”的訪問不明確cout<<"hello..."<<endl;system("pause");return ;
}
  • 抽象類和多繼承更配哦
#include <iostream>
using namespace std;class Interface1
{
public:virtual int add(int a, int b) = 0;virtual void print() = 0;
};class Interface2
{
public:virtual int mult(int a, int b) = 0;virtual void print() = 0;
};class Parent
{
public:int getA(){a = 0;return a;}
protected:
private:int a;
};class  Child : public Parent, public Interface1, public Interface2
{
public:virtual int add(int a, int b){cout<<"Child: add()已經執行\n";return a + b;}virtual void print(){cout<<"Child: print()已經執行\n";}virtual int mult(int a, int b){cout<<"Child: mult()已經執行\n";return a*b;}
protected:
private:
};void main71()
{Child c1;c1.print();Interface1 *it1 = &c1;it1->add(1, 2);Interface2 *it2 = &c1;it2->mult(3, 6);cout<<"hello..."<<endl;system("pause");return ;
}

4.面向抽象類編程

  • 計算程序猿工資
#include <iostream>
using namespace std;class programer{
public:virtual int getSal() = 0;
};class junior_programer :public programer
{
private:char *name;char *obj;int sal;
public:junior_programer(char *_name,char *_obj,int _sal){name = _name;obj = _obj;sal = _sal;}virtual int getSal(){cout << name << " " << obj << ": " << sal << endl;return sal;}
protected:
};class mid_programer :public programer
{
private:char *name;char *obj;int sal;
public:mid_programer(char *_name, char *_obj, int _sal){name = _name;obj = _obj;sal = _sal;}virtual int getSal(){cout << name << " " << obj << ": " << sal << endl;return sal;}
protected:
};class adv_programer :public programer
{
private:char *name;char *obj;int sal;
public:adv_programer(char *_name, char *_obj, int _sal){name = _name;obj = _obj;sal = _sal;}virtual int getSal(){cout << name << " " << obj << ": " << sal << endl;return sal;}
protected:
};class arch_programer :public programer
{
private:char *name;char *obj;int sal;
public:arch_programer(char *_name, char *_obj, int _sal){name = _name;obj = _obj;sal = _sal;}virtual int getSal(){cout << name << " " << obj << ": " << sal << endl;return sal;}
protected:
};void CalProgSal(programer *base)
{base->getSal();
}int main(void)
{junior_programer jp("小王", "初級", 4000);mid_programer mp("小張", "中級", 8600);adv_programer ap("小李", "高級", 15000);//系統擴展arch_programer ar("高水平學員", "架構師", 24000);CalProgSal(&jp);CalProgSal(&mp);CalProgSal(&ap);CalProgSal(&ar);cout<<"Hello!"<<endl;system("pause");return 0;
}

5.socket庫c++模型設計和實現

企業信息系統框架集成第三方產品

  • 案例背景:一般的企業信息系統都有成熟的框架。軟件框架一般不發生變化,能自由的集成第三方廠商的產品。
  • 案例需求:請你在企業信息系統框架中集成第三方廠商的Socket通信產品和第三方廠商加密產品。
    • 第三方廠商的Socket通信產品:完成兩點之間的通信
    • 第三方廠商加密產品:完成數據發送時加密;數據解密時解密。

這里寫圖片描述

案例要求:
1)能支持多個廠商的Socket通信產品入圍
2)能支持多個第三方廠商加密產品的入圍
3)企業信息系統框架不輕易發生框架
需求實現

  • 思考1:企業信息系統框架、第三方產品如何分層
  • 思考2:企業信息系統框架,如何自由集成第三方產品
    (軟件設計:模塊要求松、接口要求緊)
  • 思考3:軟件分成以后,開發企業信息系統框架的程序員,應該做什么?第三方產品入圍應該做什么?
    編碼實現

分析有多少個類 CSocketProtocol CSckFactoryImp1 CSckFactoryImp2
CEncDesProtocol HwEncdes ciscoEncdes

1、 定義 CSocketProtocol 抽象類
2、 編寫框架函數
3、 編寫框架測試函數
4、 廠商1(CSckFactoryImp1)實現CSocketProtocol、廠商2(CSckFactoryImp1)實現CSocketProtoco
5、 抽象加密接口(CEncDesProtocol)、加密廠商1(CHwImp)、加密廠商2(CCiscoImp)),集成實現業務模型
6、 框架(c語言函數方式,框架函數;c++類方式,框架類)

幾個重要的面向對象思想
* 繼承-組合(強弱)
* 注入
* 控制反轉 IOC
* MVC
* 面向對象思想擴展aop思想:aop思想是對繼承編程思想的有力的補充

實現步驟

  1. 定義socket的抽象類和純虛函數
#pragma  once#include <iostream>
using namespace std;class CSocketProtocol
{
public:CSocketProtocol(){;}virtual ~CSocketProtocol() //虛析構函數的細節{;}//客戶端初始化 獲取handle上下virtual int cltSocketInit( /*out*/) = 0; //客戶端發報文virtual int cltSocketSend( unsigned char *buf /*in*/,  int buflen /*in*/)  = 0; //客戶端收報文virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/) = 0;//客戶端釋放資源virtual int cltSocketDestory() = 0;};

2.廠商一的功能實現

  • 類的頭文件
#pragma  once#include <iostream>
using namespace std;
#include "CSocketProtocol.h"class  CSckFactoryImp1 : public CSocketProtocol
{
public://客戶端初始化 獲取handle上下virtual int cltSocketInit( /*out*/); //客戶端發報文virtual int cltSocketSend( unsigned char *buf /*in*/,  int buflen /*in*/); //客戶端收報文virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/);//客戶端釋放資源virtual int cltSocketDestory();private:unsigned char *p;int len ;
};
  • 類的實現文件
#include <iostream>
using namespace std;#include "CSckFactoryImp1.h"//客戶端初始化 獲取handle上下int CSckFactoryImp1::cltSocketInit( /*out*/){p = NULL;len = 0 ;return 0;}//客戶端發報文int CSckFactoryImp1::cltSocketSend( unsigned char *buf /*in*/,  int buflen /*in*/){p  = (unsigned char * ) malloc(sizeof(unsigned char)  * buflen);if (p == NULL){return -1;}memcpy(p, buf, buflen);len = buflen;return 0;}//客戶端收報文int CSckFactoryImp1::cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/){if (buf==NULL || buflen==NULL){return -1;}*buflen  = this->len ;memcpy(buf, this->p, this->len);return 0;}//客戶端釋放資源int CSckFactoryImp1::cltSocketDestory(){if (p != NULL){free(p);p = NULL;len = 0;}return 0;}

3.廠商二的功能實現

  • 類的頭文件
#pragma  once#include <iostream>
using namespace std;
#include "CSocketProtocol.h"class  CSckFactoryImp2 : public CSocketProtocol
{
public://客戶端初始化 獲取handle上下virtual int cltSocketInit( /*out*/); //客戶端發報文virtual int cltSocketSend( unsigned char *buf /*in*/,  int buflen /*in*/); //客戶端收報文virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/);//客戶端釋放資源virtual int cltSocketDestory();private:unsigned char *p;int len ;
};
  • 類的實現文件
#include <iostream>
using namespace std;#include "CSckFactoryImp2.h"//客戶端初始化 獲取handle上下
int CSckFactoryImp2::cltSocketInit( /*out*/)
{p = NULL;len = 0 ;return 0;
}//客戶端發報文
int CSckFactoryImp2::cltSocketSend( unsigned char *buf /*in*/,  int buflen /*in*/)
{p  = (unsigned char * ) malloc(sizeof(unsigned char)  * buflen);if (p == NULL){return -1;}memcpy(p, buf, buflen);len = buflen;return 0;
}//客戶端收報文
int CSckFactoryImp2::cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/)
{if (buf==NULL || buflen==NULL){return -1;}*buflen  = this->len ;memcpy(buf, this->p, this->len);return 0;
}//客戶端釋放資源
int CSckFactoryImp2::cltSocketDestory()
{if (p != NULL){free(p);p = NULL;len = 0;}return 0;
}

4.測試socket功能文件

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;#include "CSocketProtocol.h"
#include "CSckFactoryImp1.h"
#include "CSckFactoryImp2.h"//面向抽象類編程,框架實現完畢
int SckSendAndRec01(CSocketProtocol *sp, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{int ret = 0;ret = sp->cltSocketInit();if (ret != 0){goto End;}ret = sp->cltSocketSend(in, inlen);if (ret != 0){goto End;}ret = sp->cltSocketRev(out, outlen);if (ret != 0){goto End;}End:ret = sp->cltSocketDestory();return 0;
}//寫一個框架
int main011()
{int ret = 0;unsigned char in[4096];int inlen;unsigned char out[4096];int outlen = 0;strcpy((char *)in, "aadddddddddddaaaaaaaaaaa");inlen = 9;CSocketProtocol *sp = NULL;//sp = new CSckFactoryImp1sp = new CSckFactoryImp2; //ret = SckSendAndRec01(sp, in, inlen, out, &outlen);if (ret != 0){printf("func SckSendAndRec() err:%d \n", ret);return ret;}delete sp; //想通過父類指針 釋放所有的子類對象的資源 ..cout<<"hello..."<<endl;system("pause");return ret;
}

5.加密協議抽象類的定義

#pragma  onceclass CEncDesProtocol
{
public:CEncDesProtocol(){}virtual ~CEncDesProtocol(){}virtual int EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen) = 0;virtual int DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen) = 0;};

6.廠商一的加密功能實現

  • 類的頭文件
#include <iostream>
using namespace std;#include "CEncDesProtocol.h"class HwEncDec : public CEncDesProtocol
{
public:virtual int EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen);virtual int DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen);
};
  • 類的實現文件
#include <iostream>
using namespace std;
#include "HwEncDec.h"
#include "des.h"int HwEncDec::EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen)
{int ret = 0;//用戶使用的函數ret =  DesEnc(plain,plainlen, cryptdata, cryptlen);if (ret != 0){printf("func DesEnc() err:%d \n ", ret);return ret;}return ret;
}int HwEncDec::DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen)
{int ret = 0;//用戶使用函數des解密ret =  DesDec(cryptdata, cryptlen, plain, plainlen);if (ret != 0){printf("func DesDec() err:%d \n ", ret);return ret;}return ret;
}

7.加密功能的測試文件

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;#include "CSocketProtocol.h"
#include "CSckFactoryImp1.h"
#include "CSckFactoryImp2.h"#include "CEncDesProtocol.h"
#include "HwEncDec.h"//面向抽象類編程,框架實現完畢
int SckSendAndRec(CSocketProtocol *sp, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{int ret = 0;ret = sp->cltSocketInit();if (ret != 0){goto End;}ret = sp->cltSocketSend(in, inlen);if (ret != 0){goto End;}ret = sp->cltSocketRev(out, outlen);if (ret != 0){goto End;}End:ret = sp->cltSocketDestory();return 0;
}//面向抽象類編程,框架實現完畢
//c函數
int SckSendAndRec_EncDec(CSocketProtocol *sp, CEncDesProtocol *ed, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{int ret = 0;unsigned char data[4096];int datalen = 0;ret = sp->cltSocketInit();if (ret != 0){goto End;}ret = ed->EncData(in,inlen, data, &datalen);if (ret != 0){goto End;}ret = sp->cltSocketSend(data, datalen); //發送數據之前對數據加密 ..if (ret != 0){goto End;}ret = sp->cltSocketRev(data, &datalen); //收到的數據是密文,需要進行解密if (ret != 0){goto End;}ret = ed->DecData(data, datalen, out, outlen );if (ret != 0){goto End;}End:ret = sp->cltSocketDestory();return 0;
}//寫一個框架
int main022()
{int ret = 0;unsigned char in[4096];int inlen;unsigned char out[4096];int outlen = 0;strcpy((char *)in, "aadddddddddddaaaaaaaaaaa");inlen = 9;CSocketProtocol *sp = NULL;CEncDesProtocol *ed = NULL;//sp = new CSckFactoryImp1sp = new CSckFactoryImp2; //ed = new HwEncDec;ret = SckSendAndRec_EncDec(sp, ed, in, inlen, out, &outlen);if (ret != 0){printf("func SckSendAndRec() err:%d \n", ret);return ret;}delete sp; //想通過父類指針 釋放所有的子類對象的資源 ..cout<<"hello..."<<endl;system("pause");return ret;
}

加解密的代碼是des.h和des.c,可在前面“08文件操作”查看源代碼。

8.將測試框架從函數形式升級為類的形式

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;#include "CSocketProtocol.h"
#include "CSckFactoryImp1.h"
#include "CSckFactoryImp2.h"#include "CEncDesProtocol.h"
#include "HwEncDec.h"//抽象類在多繼承中的應用
/*
class  MainOp : public CSocketProtocol, public CEncDesProtocol
{
public:
protected:
private:};
*/class MainOp
{
public:MainOp(){this->sp = NULL;this->ed = NULL;}MainOp(CSocketProtocol *sp, CEncDesProtocol *ed){this->sp = sp;this->ed = ed;}//void setSp(CSocketProtocol *sp){this->sp = sp;}void setEd(CEncDesProtocol *ed){this->ed = ed;}public://面向抽象類編程,框架實現完畢int SckSendAndRec_EncDec3(CSocketProtocol *sp, CEncDesProtocol *ed, unsigned char *in, int inlen, unsigned char *out, int *outlen){int ret = 0;unsigned char data[4096];int datalen = 0;ret = sp->cltSocketInit();if (ret != 0){goto End;}ret = ed->EncData(in,inlen, data, &datalen);if (ret != 0){goto End;}ret = sp->cltSocketSend(data, datalen); //發送數據之前對數據加密 ..if (ret != 0){goto End;}ret = sp->cltSocketRev(data, &datalen); //收到的數據是密文,需要進行解密if (ret != 0){goto End;}ret = ed->DecData(data, datalen, out, outlen );if (ret != 0){goto End;}End:ret = sp->cltSocketDestory();return 0;}int SckSendAndRec_EncDec3(unsigned char *in, int inlen, unsigned char *out, int *outlen){int ret = 0;unsigned char data[4096];int datalen = 0;ret = this->sp->cltSocketInit();if (ret != 0){goto End;}ret = this->ed->EncData(in,inlen, data, &datalen);if (ret != 0){goto End;}ret = this->sp->cltSocketSend(data, datalen); //發送數據之前對數據加密 ..if (ret != 0){goto End;}ret = sp->cltSocketRev(data, &datalen); //收到的數據是密文,需要進行解密if (ret != 0){goto End;}ret = ed->DecData(data, datalen, out, outlen );if (ret != 0){goto End;}End:ret = sp->cltSocketDestory();return 0;}private:CSocketProtocol *sp;CEncDesProtocol *ed;};//寫一個框架
int main()
{int ret = 0;unsigned char in[4096];int inlen;unsigned char out[4096];int outlen = 0;strcpy((char *)in, "aadddddddddddaaaaaaaaaaa");inlen = 9;MainOp *myMainOp = new MainOp;CSocketProtocol *sp = NULL;CEncDesProtocol *ed = NULL;//sp = new CSckFactoryImp1sp = new CSckFactoryImp2; //ed = new HwEncDec;myMainOp->setSp(sp);myMainOp->setEd(ed);ret = myMainOp->SckSendAndRec_EncDec3(in, inlen, out, &outlen);if (ret!= 0){printf("myMainOp SckSendAndRec_EncDec3() err\n ", ret);}delete sp;delete ed;delete myMainOp;cout<<"hello..."<<endl;system("pause");return ret;
}

無非就是將之前的全局函數封裝在一個測試用的類里面,然后該測試類擁有socket和加解密協議的基類對象作為該測試類的成員變量。

6.C語言回調函數和函數指針

這里寫圖片描述

結論:回調函數的本質:提前做了一個協議的約定(把函數的參數、函數返回值提前約定)

這里寫圖片描述
動態庫升級為框架的編碼實現
1、 動態庫中定義協議,并完成任務的調用

typedef int (*EncData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);
typedef int (*DecData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);

2、 加密廠商完成協議函數的編寫
3、 對接調試。
4、 動態庫中可以緩存第三方函數的入口地址,也可以不緩存,兩種實現方式。

案例總結

  • 回調函數:利用函數指針做函數參數,實現的一種調用機制,具體任務的實現者,可以不知道什么時候被調用。

  • 回調機制原理:

    • 當具體事件發生時,調用者通過函數指針調用具體函數
    • 回調機制將調用者和被調函數分開,兩者互不依賴
    • 任務的實現 和 任務的調用 可以耦合 (提前進行接口的封裝和設計)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448357.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448357.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448357.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決: -bash: $‘\302\240docker‘: command not found

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 我只是運行 一條很簡單的啟動容器的命令&#xff0c;多次執行都報錯&#xff0c;報錯如題&#xff1a; -bash: $\302\240docker: comma…

換擋/掛檔

定義 換擋/掛檔是指變速器&#xff0c;用于轉變發動機曲軸的轉矩及轉速&#xff0c;以適應汽車在起步、加速、行駛以及克服各種道路阻礙等不同行駛條件下對驅動車輪牽引力及車速不同要求的需要。作用 使汽車能以非常低的穩定車速行駛&#xff0c;而這種低的轉速只靠內然…

sql:無法解決 equal to 操作中 Chinese_PRC_CI_AS 和 Chinese_Taiwan_Stroke_CI_AS 之間的排序規則沖突。...

--無法解決 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_Taiwan_Stroke_CI_AS" 之間的排序規則沖突。 CREATE VIEW View_VipBranchStaffBranchList AS select VipBranchStaff.*,geovindu_branch.B_Name,VipExamCountry.ExamCountryName from VipBran…

【汽車取證篇】GA-T 1998-2022《汽車車載電子數據提取技術規范》(附下載)

【汽車取證篇】GA-T 1998-2022《汽車車載電子數據提取技術規范》&#xff08;附下載&#xff09; GA-T 1998-2022《汽車車載電子數據提取技術規范》標準—【蘇小沐】 總結 公眾號回復關鍵詞【汽車取證】自動獲取資源合集&#xff0c;如鏈接失效請留言&#xff0c;便于…

解決: Client does not support authentication protocol requested by server; consider upgrading MySQL

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 在服務器上把 mysql 裝好后&#xff0c;運行起來。 2. navicat 死活連接不上&#xff0c;在網上查說是要改數據庫賬號、密碼什么的&…

C++之STL理論基礎

1.基本概念 STL&#xff08;Standard Template Library&#xff0c;標準模板庫)是惠普實驗室開發的一系列軟件的統稱。雖然主要出現在C中&#xff0c;但在被引入C之前該技術就已經存在了很長的一段時間。 STL的從廣義上講分為三部分&#xff1a;algorithm&#xff08;算法&am…

方向盤

定義 方向盤是汽車、輪船、飛機等的操縱行駛方向的輪狀裝置。 構成 一般由骨架和發泡組合起來就是最簡單的方向盤了&#xff0c;而方向盤上都會有和主駕駛氣囊對應的安裝卡扣或螺釘孔&#xff0c;其下方一般會有多功能開關模塊。作用 方向盤不僅可以控制車輛的方向…

數據庫范式俗話

1NF&#xff1a;一個table中的列是不可再分的&#xff08;即列的原子性&#xff09; 2NF&#xff1a;一個table中的行是可以唯一標示的&#xff0c;&#xff08;即table中的行是不可以 重復的&#xff09; 3NF&#xff1a;一個table中的列不依賴于另一個table中的非主鍵列 4NF&…

STL之string類型

1.String概念 string是STL的字符串類型&#xff0c;通常用來表示字符串。而在使用string之前&#xff0c;字符串通常是用char*表示的。 string和char*的區別&#xff1a; string是一個類, char*是一個指向字符的指針。 string封裝了char*&#xff0c;管理這個字符串&#x…

解決maven打包報錯:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、報錯經歷&#xff1a; 今天使用eclipse通過maven install打war包的時候&#xff0c;出現了下圖所示的錯誤 二、問題分析&#xff1a…

離合器

離合器的定義 汽車離合器位于發動機和變速箱之間的飛輪殼內&#xff0c;用螺釘將離合器總成固定在飛輪的后平面上&#xff0c;離合器的輸出軸就是變速箱的輸入軸。在汽車行駛過程中&#xff0c;駕駛員可根據需要踩下或松開離合器踏板&#xff0c;使發動機與變速箱暫時分離和…

Python 刪除滿足條件的某些行

數據&#xff1a; data 字段&#xff1a;col 要刪除的內容是 col False 的行 # 方案一 data1 data[~data[col] False] # ~ 取反# 方案二 保留 data[已采] ! False ind data[col] ! False data2 data.loc[ind,]# 方案三 去掉 data[已采] True ind2 data[col] False…

STL之Vector

1.簡介 vector是將元素置于一個動態數組中加以管理的容器。可以隨機存取元素&#xff08;支持索引值直接存取&#xff0c;用[]操作符或at()方法&#xff0c;還支持迭代器方式存取&#xff09;。   vector尾部添加或移除元素非常快速。但是在中部或頭部插入元素或移除元素比…

解決 : Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 執行 maven install 命令報錯如題&#xff1a; Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:comp…

制動踏板

什么是制動踏板 制動踏板就是限制動力的踏板&#xff0c;即腳剎(行車制動器)的踏板&#xff0c;是長時間摩擦導致剎車片過熱軟化的原因。制動踏板的作用 其主要作用是剎車減速或停車。 制動踏板的工作原理 在機器的高速軸上固定一個輪或盤&#xff0c;在機座上安裝…

實現一個用戶取過的數據不被其他用戶取到

實現一個用戶取過的數據不被其他用戶取到: 問題&#xff1a; 在用ADO訪問數據庫時&#xff0c;從一個表中取一定的記錄&#xff08;比如20行&#xff09;&#xff0c;取出后在程序中使用&#xff0c;使用完后刪除掉記錄&#xff08;不用更新或刪除記錄&#xff09;。在多用戶操…

Docker 鏡像 重命名

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 鏡像改名命令格式&#xff1a; # 命令格式&#xff1a;docker tag 鏡像id 倉庫&#xff1a;標簽或&#xff1a;docker tag 舊鏡…

STL之deque和其他容器

deque簡介 deque是“double-ended queue”的縮寫&#xff0c;和vector一樣都是STL的容器&#xff0c;deque是雙端數組&#xff0c;而vector是單端的。 deque在接口上和vector非常相似&#xff0c;在許多操作的地方可以直接替換。 deque可以隨機存取元素&#xff08;支持索引…

Java藍橋杯02——第二題集錦:生日蠟燭、星期一、方格計數、猴子分香蕉

第二題 生日蠟燭(結果填空) 某君從某年開始每年都舉辦一次生日party&#xff0c;并且每次都要吹熄與年齡相同根數的蠟燭。 現在算起來&#xff0c;他一共吹熄了236根蠟燭。 請問&#xff0c;他從多少歲開始過生日party的&#xff1f; 請填寫他開始過生日party的年齡數。 注意&a…

夜考

夜考內容 夜考主要考察夜間汽車燈的使用。上車前準備 1、向考官報告 2、繞車一周觀察車輛狀況 3、觀察車前道路上是否有障礙 4、觀察后方是否有來車 注意事項 1、發動車輛時&#xff0c;記得打開車燈; 2、會車時&#xff0c;距來車150米左右&#xff0c;使用近光燈;…