C++遠征篇匯總
C++遠征篇匯總
(一)C++遠征之起航篇
初識C++
第一章. 初識C++
(一)
C++的起源:
1.誕生地:貝爾實驗室(Bell Lab)
2.C++之父:比雅尼 ? 斯特勞斯特魯普博士(為人低調,有問必答)
C++的應用領域:1. 嵌入式,如手機,電視機等、2. 游戲編程 、3. 網絡編程、4. 系統編程
C++與C的關系:
1.從語法角度上來講:C是C++的子集
2.從歷史角度上來講:C++ 是從C的基礎上發展而來的, C語言面向過程, 而C++支持面向過程+支持面向對象
3.學習C++需要C語言的基礎,相關網址為:http://imooc.com/learn/249
C++ IDE環境搭建:
1.IDE環境:Integrated Development Environment(集成開發環境)一般包括代碼編輯器、編譯器、調試器和圖形用戶界面等工具、一般常使用的工具:Visual Studio 2010旗艦版、Visual Assist X for Visual Studio、Dev C++、CLion等
2.IDE初體驗——Visual Studio 2019的使用中存在的問題:
為了圖節省的硬盤空間,少下了一些東西,例如NET的移動開發,和個別C++ 程序應用過程中的必要負載,如C++桌面開發 ,針對已安裝好,才后悔的人(例如我(~ ̄▽ ̄)~)我提供了以下解決方案:
首先,在該路徑(C:\Program Files (x86)\Microsoft Visual Studio\Installer)中找一個叫setup的應用程序,也就是Visual Studio 2019的安裝程序(一般這個路徑是默認的,你就算在安裝時換了安裝路徑,安裝完以后,它依然在哪里);其次,打開后你可以看到在Visual Studio哪里有一個修改按鈕,之后便可以進行修改,重新再來了。
在你的項目(project)上右擊鼠標,在彈出菜單上選擇最后一項“property/屬性”,在左邊的一欄里找到“配置屬性->鏈接器->系統”,點擊“系統”項;在右邊的欄的“子系統(subSystem)”將刻項的值配置為"Console(控制臺/SUBSYSTEM:CONSOLE)"。
C++的基本了解
新數據類型
新的初始化方法
復制初始化(同C) int x=1024
直接初始化 int x(1024)
隨用隨定義
輸入和輸出方式
輸入:cin
輸出:cout
Ps: oct、dec、hex分別是8進制、10進制、16進制的英文縮寫,如輸出一個八進制數(C++): cout< 命名空間(namespace) 即劃片取名字 樣例: 定義: 輸出調用: namespace A cout< 注意:命名空間的名字是不可以重復的,如使用cout和cin函數時,要包含iostream頭文件和using namespace std;命名空間 (二) C++遠征之離港篇 引用 int a=3; int &b=a;//引用必須初始化 引用方式: Coor c1;(對象實例化) Coor&c=c1 *&指針引用名=指針; int a=10; int *p=&a;(這里p取a的值,為10) int *&q=p; void fun(int *a, int *b) 在使用引用后: { void fun(int &a, int &b) int c=0; { c=*a; int c=0; *a=*b; c=a; *b=c; a=b; } b=c;} 在調用上: 在調用上: int x=10,y=20; int x=10,y=20; fun(&x,&y); fun(x,y); 注意:引用不能單獨存在,如int &a; int b;就是錯的 const const與指針類型 const int*(const)p=NULL; int const* (const) p=NULL int*const p=NULL; 限定了p 原因是,const使x和p都變成了常量,均不可被改變,也不可被變量引用 const與引用 int x=3;const int &y=x;//x=10;正確 //y=20;錯誤 一些函數新特性 函數參數默認值 有默認參數值的參數必須在參數表的最右端 如:void fun(int i,int j=5,int k=10); 無實參則用默認值,否則實參覆蓋默認值 函數重載:在相同作用域內,用同一函數名定義的多個函數,且在多個函數中參數個數和參數類型是不同的 例如:int getMax(int x, int y, int z){ //to do} /double getMax(double x,double y){//to do} 計算機編譯好后形成的新的參數: getMax_int_int_int getMax_double_double 優勢:1) 提高了代碼命名時的準確性和高效性;2) C++的重載的兩個函數參數數量可以相同也可以不同,當參數數量相同時,只需要對應參數類型不同即稱為重載 內聯函數關鍵字:inline 例子: inline int max(int a,int b,int c); int main() { int i=10,j=20,k=30,m; m=max(i,j,k); 代碼展開: int a,b,c; a=i;b=j,c=k; if(b>a) a=b; if(c>a) a=c; m=a; cout<<"max="< 注意點: ->內聯編譯是建議性的,由編譯器決定 ->邏輯簡單,調用頻繁的函數建議使用內聯 ->遞歸函數無法使用內聯方式 內存管理 申請/歸還內存資源就是內存管理 內存的申請和釋放 內容總結 使用new申請內存,使用delete釋放內存 申請內存需要判斷是否成功,釋放內存需要設空指針 new與delete配套使用 申請內存 運算符new : int *p=new int(20);/ int *arr=new int[10]; 注意:int *p = new int [20]; delete []p;申請的是空間數組,而 int *p = new int (20); delete p;申請的是內存空間 釋放內存 運算符delete : delete p;/ delete[]arr; 申請內存注意事項: int *p=new int [1000]; if(NULL==p){//內存分配失敗} C++遠征之封裝篇 封裝篇(上) 類的定義 關鍵字->class Dog<——類名 { char name[20]; int age; <——數據成員(屬性) int type; void speak(); void run(); <————————成員函數(方法) }; 類是抽象的概念,對象是具體的事物 定義類應當使用關鍵字class 訪問限定符 public: 公共的 protected: 受保護的 private: 私有的 對象實例化 從棧實例化 從堆實例化 字符串類型:string 栗子: #include >面向對象的基本思想: 對象的所有行為都通過調用函數完成 >定義在類里面的變量規范,如string類型的,寫為m_strName; int類型的,寫為:m_iName 內存分區 棧區: int x=0; int *p=NULL; 堆區: int *p = new int[20]; 全局區: 存儲全局變量及靜態變量 常量區: string str = "hello"; 代碼區:存儲邏輯代碼的二進制 有且僅有一次 根據條件初始化 構造函數的規則和特點 - 構造函數在對象實例化時被自動調用 - 構造函數與類同名 - 構造函數沒有返回值 - 構造函數可以有多個重載形式 - 實例化對象時僅用到一個構造函數 - 當用戶沒有定義構造函數時,編譯器自動生成一個構造函數 無參構造函數 class Student { public: Student(){m_strName = "jim";} private: string m_strName; }; 默認構造函數 構造函數初始化列表 class Student { public: Student():m_strName("Jim"),m_iAge(10){} private: string m_strName; int m_iAge; }; 初始化列表特性 初始化列表先于構造函數執行 初始化列表只能用于構造函數 初始化列表可以同時初始化多個數據成員 初始化列表存在的必要性 有參構造函數 class Student { public: Student(string name) {m_strName = name;} private: string m_strName; }; 參數帶默認值 參數無默認值 class Student { public: Student(){m_strName = "jim";} Student(string name) {m_strName = name;} private: string m_strName; }; 拷貝構造函數 定義格式:類名(const 類名&變量名) class Student { public: Student(){m_strName = "jim";} Student(const Student& stu){} private: string m_strName; }; 注意點: 析構函數 定義格式: ~類名() class Student { public: Student() {m_pName = new char[20];} ~Student() {delete [] m_pName;} private: char *m_pName; }; 如果沒有自定義的析構函數則系統自動生成 析構函數在對象銷毀時自動調用 析構函數沒有返回值、沒有參數也不能重載 封裝篇(下) 對象成員與對象數組 對象數組 定義: class Coordinate { public: int m_iX; int m_iY; }; 使用時: int main(void) { Coordinate coord[3]; //棧上 coord[1].m_iX=10; Coordinate *p = new Coordinate[3]; //堆中 p[0].m_iY = 20; p->m_iY = 20; delete []p; p = NULL; return 0; } 注意點: 1. 堆中實例化的數組需要手動銷毀釋放內存,在棧中實例化的數組,系統自動回收內存 2. 實例化對象數組時,每一個對象的構造函數都會被執行。 3. 實例化對象數組時,內存既可以從堆上分配,也可以從棧上分配。 4. 銷毀對象數組時,每一個對象的析構函數都會被執行。 對象成員 1. 坐標類的構造函數是需要有參數的 2. 對象成員在調用構造函數的順序是從里往外,在調用析構函數的時候是從外往里 點的定義 class Coordinate { public: Coordinate(int x, int y); private: int m_iX; int m_iY; }; 線段的定義 class Line { public: Line(); private: Coordinate m_coorA; Coordinate m_coorB; }; 例子: class Array { public: Array(){m_iCount = 5;} Array(const Array& arr) {m_iCount=arr,m_iCount;} private: int m_iCount; }; int main(void) { Array arr1; Array arr2=arr1;(在這里,arr1=m_iCount,而arr2=arr,m_iCount;) return 0; } 淺拷貝所帶來的劣勢: 當拷貝指針類型的相關函數時,會使得拷貝的函數與原先的函數指向同一個地址,進而可能造成系統的崩潰 小知識:快速注釋掉代碼的快捷鍵:Ctrl+k+c(適用于Visual Studio) 對象指針 即用指針來指向一個對象 int main(void) { Coordinate *p=new Coordinate; p->m_iX=10; //(*p).m_iX=10; p->m_iY=20; //(*p).m_iY=20; delete p; p=NULL; return 0; } 對象成員指針 定義: class Line { public: Line(); ~Line(); private: Coordinate *m_pCoorA; Coordinate *m_pCoorB; }; 內存中的對象成員指針 一個指針占4個內存單元,一共占了八個 用于解決參數與數據成員同名所引起的系統報錯問題 class Array { public: Array(int len){this->len=len;} int getLen(){return len;} void setLen(int Len){this->len=len;} private: int len; }; this指針在參數列表中的位置 class Line { public: Line(int x1,int y1,int x2,int y2); private: const Coordinate m_coorA; const Coordinate m_coorB; }; 常成員函數 class Coordinate { public: Coordinate(int x,int y); void changeX() const; <——常成員函數 void changeX(); private: int m_iX; int m_iY; } 常指針與常引用 常指針 const Coordinate *pCoor=&coor1; 常引用 const Coordinate &coor2=coor1; 一個對象可以有多個對象常引用 常指針和常引用都只能調用對象的常成員函數 普通對象能夠調用常成員函數,也能夠調用普通成員函數 常對象只能調用常成員函數,不能調用普通成員函數 C++遠征之繼承篇 什么是繼承 class Worker: public Person { public: void work(); int m_iSalary; }; 其中: 派生類(子類)——>class Worker 基類(父類)——>public Person 繼承的相關注意點 被繼承的類叫做基類也叫做父類,從其他類繼承而來的類叫做派生類也叫做子類。 子類中不僅繼承了父類的中的數據成員,也繼承了父類的成員函數。 C++中的繼承關系是概念上的父子關系,不是個體的父子關系。 類與類之間必須遵循概念上的父子關系,否則將造成定義和使用的混亂 繼承方式 公有繼承 class A: public B 保護繼承 class A: protected B 私有繼承 class A: private B B類從A類派生,那么B類是A類的子類,A類是B類的超類。 B類從A類派生,那么B類中含有A類的所有數據成員。 B類從A類公共派生,那么通過B類的對象只能調用到A的公共及保護限定符下的成員函數 B類從A類公共派生,那么可以在B類中直接使用A的公共及保護限定符的數據成員。 繼承中的特殊關系 隱藏 關鍵字:父子關系、成員同名、隱藏 Is-a 存儲結構 虛析構函數 多繼承與多重繼承 多重繼承 class Person { }; class Soldier: public Person { }; class Infantryman: public Soldier { }; 多繼承 class Worker { }; class Farmer { }; class MigrantWorker: public Worker, public Farmer { }; 注意點 多繼承是指一個子類繼承多個父類 多繼承對父類的個數沒有限制,繼承方式可以是公共繼承、保護繼承和私有繼承。 多重繼承與多繼承不同,當B類從A類派生,C類從B類派生,此時成為多重繼承。 虛繼承 關鍵字:virtual 使用方法: class Worker: virtual public Person { }; class Farmer: virtual public Person { }; 小知識:用以解決重定義的相關bug #ifndef 文件名稱,如:#ifndef PERSON_H #define 文件名稱,如:#define PERSON_H … #endif C++遠征之多態篇 虛函數及實現原理 虛函數 多態 什么是多態 指相同對象收到不同消息或不同對象收到相同消息時產生不同的動作 分類 靜態多態(早綁定) 動態多態(晚綁定) virtual->虛函數 實例 class Shape { public: virtual double calcArea() //虛函數 { cout<<"calcArea"< 相關注意點 1. 多態具體到語法中是指,使用父類指針指向子類對象,并可以通過該指針調用子類的方法。 2. 產生多態的基礎是繼承關系,沒有繼承就沒有多態 3. 多態的語法核心是virtual關鍵字,必須使用virtual才能使多個類間建立多態關系。 4. 封裝、繼承、多態是面向對象的三大特性。 虛析構函數 多態中存在的問題 內存泄露 int main(void) { Shape *shape1=new Circle(3,5,4.0); shape1->calcArea(); delete shape1; shape1=NULL; return 0; } 1)普通函數不能是虛函數 2)靜態成員不能是虛函數 3)內聯函數不能是虛函數 4)構造函數不能是虛函數 1. 虛函數使用virtual關鍵字定義,但使用virtual關鍵字時,并非全部是虛函數 2. 虛函數特性可以被繼承,當子類中定義的函數與父類中虛函數的聲明相同時,該函數也是虛函數。 3. 虛析構函數是為了避免使用父類指針釋放子類對象時造成內存泄露。 virtual->析構函數 實現原理 函數指針 理論前提:執行完子類的析構函數就會執行父類的析構函數 在C++中多態的實現是通過虛函數表實現的 當類中僅含有虛析構函數,不含其它虛函數時,也會產生虛函數表 每個類只有一份虛函數表,所有該類的對象共用同一張虛函數表 兩張虛函數表中的函數指針可能指向同一個函數。 純虛函數和抽象類 運行時類型識別 異常處理 C++遠征之模板篇 友元函數和友元類 友元函數 友元全局函數 class Coordinate { friend void printfXY(Coordinate &c); public: Coordinate(int x,int y); private: int m_iX; int m_iY; }; 友元成員函數 class Coordinate { friend void Circle::printXY(Coordinate &c); public: Coordinate(int x,int y); private: int m_iX; int m_iY; }; 友元類 class Circle; class Coordinate { friend Circle; public: Coordinate(int x,int y); private: int m_iX; int m_iY; }; 劣勢:易破壞函數的封裝性,且不易被察覺 關于友元的注意事項 友元關系不可傳遞 友元關系的單向性 友元聲明的形式及數量不受限制 友元只是封裝的補充 靜態 普通數據成員與靜態數據成員的區別 靜態數據成員是依賴于類的,而普通數據成員則是依賴于對象的 靜態數據成員必須單獨初始化 靜態成員函數不能調用非靜態成員函數和非靜態數據成員 靜態數據成員只有一份,且不依賴對象而存在 運算符重載 給原有運算符賦予新功能 關鍵字:operator 一元運算符重載 實際上就是只與一個操作數進行運算 二元運算符重載 模板函數與模板類 函數模板 關鍵字: template 、 typename 、 class 例子 template 類模板 定義 template 類外定義 template 使用 int main(void) { MyArray 定義一個類模板就相當于定義了一系列功能相同類型不同的類 定義類模板需要使用關鍵字template 定義類模板的參數可以使用typename和class,可以混用 模板參數既可以是類型,也可以是變量 標準模板類 本質:對數組的封裝 特點:讀取能在常數時間完成 1. vector是對數組的封裝,大小可以根據元素數量改變 2. map需要與pair一起使用,用來存儲多個key-value對。 3. 不同廠商的標準模板庫的實現細節可以不同,基本用法及原理相同。 調用的函數庫:include C++ 嵌入式
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。