C++學習總結,學霸課堂筆記
時間:2018-08-23 來源:未知
Day1
名字空間:用來限制作用域(重名問題)
Using namespace std; 全局的聲明,只有一次聲明之后使用的std中的東西就可以直接用。
::std 全局
Using myspace ::demo 使用myspace中的demo。
換行: endl \n
cin >> ival >> ch
cout << ival << ch << endl
————————————
Oop思想:面向對象的思想
屬性+行為=對象
(記憶 體會 實踐 理解 發(fā)揮)
類的聲明定義:(聲明與定義分開)
Class 聲明類
Class Demo(類名)
成員的性質(public 公共 ———— private 私有(一般數(shù)據(jù)私有) ———— protected 保護)
——————————
構造函數(shù):不需要用戶來調用它也不能調用,而是在建立對象時自動執(zhí)行
構造函數(shù)的名字必須與類名同名,而不能由用戶任意命名,以便以其系統(tǒng)能識別它并把它作為構造函數(shù)處理
構造函數(shù)的功能是由用戶定義的,用戶根據(jù)初始化的要求設計函數(shù)體和函數(shù)參數(shù)
如果用戶不設計,則編譯器自動生成一個默認構造函數(shù)
無返回值
普通默認構造
拷貝構造 用已有的構造新的
深拷貝和淺拷貝 默認的拷貝函數(shù)為淺拷貝,當有指針類成員時一定要自己做拷貝函數(shù)做深拷貝(使得數(shù)據(jù)區(qū)域獨立 不光是拷貝值)
Demo(const Demo & )
限制構造 類中的成員屬于私有或者保護 不允許構造
——————————
析構函數(shù): 對象銷毀時自動調用(對于同一生命周期的成員 先構造的后析構 )
不能重載
只能用~Demo()
全局對象,進程結束時對象自動銷毀,析構自動調用
局部對象,func()調用構造,func結束析構
靜態(tài)局部對象,進程生命期,func第一次調用構造,進程結束析構
堆對象,運行時候構造,必須是delete對象才會銷毀,且自動析構,如果不delete就不析構
————————————
This 指針:
指向對象自己
Private 成員 只能在內部使用
Const 成員 不可修改
————————————
分析構造和析構的次數(shù)
——————————————————————————————————————————————————
Day3
Static :
Static 成員 (靜態(tài)成員是一種特殊成員)
不屬于任何類對象(有沒有對象都靜態(tài)成員就已經存在,且是進程生命期)
作用域在類域
靜態(tài)的,唯一的
用于限制作用域
————————————
Const :
Const 成員函數(shù) 在函數(shù)后面加const,表示該成員函數(shù)不能修改類對象(在這個函數(shù)內不能存在修改類對象的任何操作)
只要類方法不修改對象就應該聲明為const
Const 對象 const Demo obj; //只讀對象,不能被修改(obj 被定義為Demo類的只讀對象不可以被修改)
只要調用成員函數(shù),就存在修改對象的風險,所以不能再調用成員函數(shù)。語法上不允許調用普通成員函數(shù)
Const 成員變量 const int x
只讀成員變量,那么必須使用初始化列表進行初始化
Demo::Demo(int a) : x(a) //初始化列表
只要調用x就會檢查會不會修改,x被const修飾所以不能被修改。
————————————
友元:(打破封裝可訪問類中的private protected對象)
友元的聲明可以放在類的私有部分,也可以放在公有部分,它們是沒有區(qū)別的
慎用友元,存在危險性。
友元函數(shù) 一個函數(shù)可以是多個類的友元函數(shù),只需要在各個類中分別聲明。調用與一般函數(shù)的調用方法和原理一致
友元類 友元關系不能被繼承,是單向的,不具有傳遞性
聲明友元類時需要前項聲明(前項聲明可以不列出具體內容)
友元成員函數(shù) 存在遞歸可能 所以最好聲明定義引用分開編寫。
前項聲明不足以完全說清楚所以分開編寫。
————————————————————————————————————————————————————————————————
Day4
運算符重載:(重載——函數(shù)同名,參數(shù)不同,行為相似)
運算符重載——特殊的一種重載 (加 operator)
友元運算符重載 與函數(shù)對比,功能相同
friend const int* getaddr(const Demo &);
friend Demo& addeq(Demo &, const Demo &);
函數(shù)實現(xiàn)功能不直觀不容易被理解
friend const int* operator& (const Demo &);
friend Demo& operator += (Demo &, const Demo &);
運算符重載實現(xiàn)功能直觀便于理解
friend Demo& operator ++ (Demo &); 前++
friend Demo& operator ++ (Demo &,int);后++
——————————
成員函數(shù)運算符重載 成員函數(shù)在類中 屬于類 可以使用this 指針所以成員函數(shù)的運算符重載在傳參數(shù)時 參數(shù)個數(shù)和友元運算符重載不同。
bool operator !=(Integer &)
bool是判斷返回值(對或者錯)
【】通過數(shù)組名[]訪問數(shù)組成員,即得到一個對象
通過數(shù)組名[]訪問數(shù)組成員,即得到一個對象,
對象有一個運算符[]得到對象管理的整型數(shù)組的一個整型
arr[0]:IntArray對象
arr[0][0]:是一個整型
————————————
注意事項 除關系運算符“.”、作用域運算符“::”、sizeof運算符和三目運算符“:?”外,C++中的所有運算符都可以重載(其中“=”和“&”不必用戶重載)
重載運算符限制限制在C++語言中已經有的運算范圍內的允許重載的運算符之中,不能創(chuàng)建新的運算符。
運算符重載的實質就是函數(shù)重載,遵循函數(shù)重載的選擇原則
重載之后的運算符不能改變運算符的優(yōu)先級和結合性,也不能改變運算符操作數(shù)的個數(shù)及語法結構
運算符重載不能改變該運算符用于內部類型的對象的含義
運算符重載是針對新類型數(shù)據(jù)的實際需要對原有運算符進行的適當?shù)母脑欤剌d的功能應當與原有功能相類似,避免沒有目的地使用重載運算符
重載運算符的函數(shù)不能有默認參數(shù),否則就改變了運算符的參數(shù)個數(shù)
重載的運算符只能是用戶自定義類型,否則就不是重載而是改變了現(xiàn)有的C++標準數(shù)據(jù)類型的運算符的規(guī)則
運算符重載可以通過成員函數(shù)的形式,也可以通過友元函數(shù)的形式,和非成員的普通函數(shù)
————————————————————————————————————————————————————
Day 5
模板:模板是對一種對類型進行參數(shù)化的工具。
模板的聲明或者定義只能在全局,命名空間或者類范圍內進行。即不能在局部范圍,函數(shù)內進行。
函數(shù)模板 參數(shù)類型不一樣的但是功能及函數(shù)名一樣的函數(shù)
函數(shù)模板的聲明定義語法上差異不大,就像普通函數(shù)一樣使用
template
T add(T x, T y);
template
C add(C x, C y)
{
return x+y;
}
類模板 成員屬性的類型和成員函數(shù)的類不一樣但是成員屬性及函數(shù)一樣的類
template
class Demo{
public:
Demo(T1 a, T2 b);
void setx(T1 a);
static void sety(Demo &, T2 val);
T1 getx() const;
T2 gety() const;
private:
static T1 x;
T2 y;
};
友元函數(shù)模板
如果一個類是模板類,又要實現(xiàn)運算符重載,就是一個友元函數(shù)模板;
實質是類模板和函數(shù)模板的綜合運用
template
class Demo{
public:
Demo(const int val);
public:
T getval() const;
void setval(const int val);
template
friend Demo
private:
T ival;
};
非類型模板參數(shù)
template
class Array{
public:
Array();
Array(const Array &);
~Array();
public:
T& at(const int id=0) const;
T& operator[](const int id)const;
private:
T* const buffer;
};
T:模板類型參數(shù);len:模板非類型參數(shù);T、len都可以有默認值
————————————————————————————————————————————
Day 6
繼承: 就是在一個已存在的類的基礎上建立一個新的類。已存在的類(學生)稱為“基類”(或父類),新建立的類(小學生)稱為“派生類”(或子類)
1.派生類繼承了基類的所有數(shù)據(jù)成員和成員函數(shù)(private雖然也繼承了,但是無法直接訪問),并可以對成員作必要的增加和調整。
2.一個基類可以派生出多個派生類,每一個派生類又可以作為基類再派生出新的派生類,因此基類和派生類是相對而言的。
3.派生類是基類的具體化,而基類則是派生類的抽象。
繼承權限 :
1.public:公有繼承。
a.公有成員變成派生類的公有成員。 b.保護成員變成派生類的保護成員。 c.私有成員:只能通過基類接口訪問。
2.protected:保護繼承。
a.公有成員,保護成員都變成派生類的保護成員 b.私有成員:只能通過基類接口訪問。
3.private:私有繼承。
a.公有成員,保護成員都變成派生類的私有成員 b.私有成員:只能通過基類接口訪問。
子類的構造析構:
順序——構造:先基類、再派生;析構:先派生、再基類
(因為派生類的構造和析構 可能會用到基累的成員,所以派生的構造在基類后,派生的析構在基類前)
Is-a
什么是a (香蕉是水果 水果為a是基類 )
Has-a
什么有a
(思想要理解 咋實踐中深入)
多重繼承:
class <派生類名> : <繼承方式1> <基類名1>,<繼承方式2><基類名2>……
使用需要注意 容易引起歧義
————————————————————————————————————————————————————————————————
Day 7
多態(tài):多種狀態(tài)(一個接口, 多種方法) 程序運行時才決定調用的函數(shù),是面向對象編程領域的核心概念。
多態(tài)是將接口和實現(xiàn)進行分離,(實現(xiàn)以共同的方法,但因為個體差異,而采用不同的策略)
多態(tài)的應用場景
如果基類實現(xiàn)不是我們想要的方法,那么在子類派生時,重寫一個新的版本
這樣其他成員函數(shù)不可以直接復用,這樣的情況就需要虛函數(shù),即多態(tài)
虛函數(shù) 子類和基類有相同的方法,但是行為卻有所不同(多態(tài))
(is-a 的關系不是多態(tài),函數(shù)重載(函數(shù)行為相似)也不是多態(tài))
用virtual修飾成員函數(shù)(虛函數(shù))
1. 非類的成員函數(shù)不能定義為虛函數(shù)
2. 類的靜態(tài)成員函數(shù)不能定義為虛函數(shù)
3. 構造函數(shù)不能定義為虛函數(shù),(析構可以定義為虛函數(shù))
4. 只需要在聲明函數(shù)的類體中使用關鍵字virtual將函數(shù)聲明為虛函數(shù),而定義函數(shù)時不需要再使用關鍵字virtual
5. 當將基類中的某一成員函數(shù)聲明為函數(shù)后,派生類中的同名函數(shù)(函數(shù)名相同,參數(shù)列表完全一致,返回值類型相關)自動成為虛函數(shù)
抽象類 隱藏類的其他成員的方法。
1. 含有純虛函數(shù)的類就是抽象類
2. 抽象類沒有完整的信息,只能是派生的基類
3. 抽象類不能有實例,不能有靜態(tài)成員
4. 派生類應該實現(xiàn)抽象類的所有方法
5. 抽象類不能定義對象,因為其純虛函數(shù)只有聲明沒有定義
6. 抽象類被使用只能派生,且只有有子類對象
虛析構 由于指針指向的對象是基類類型,所以delete銷毀對象的時候,并不會調用派生類的析構函數(shù),這樣級造成了對象銷毀不完整。
工程原則:只要該類要被繼承,則析構必須是虛函數(shù)
構造函數(shù)不能為虛,析構函數(shù)一定為虛
virtual ~Base() const = 0 純虛析構函數(shù)
虛繼承 解決從不同途徑繼承來的同名的數(shù)據(jù)成員在內存中有不同的拷貝造成數(shù)據(jù)不一致的問題,將共同基類設置為虛基類。
從不同的路徑繼承過來的同名數(shù)據(jù)成員在內存中就只有一個拷貝,同一個函數(shù)名也只有一個映射。
typeid(this).name() 類名
聯(lián)編(鏈接) 將模板或者函數(shù)合并在一起生成可執(zhí)行代碼的處理過程。
靜態(tài)聯(lián)編(靜態(tài)鏈接) 在編譯階段就將函數(shù)實現(xiàn)和函數(shù)調用聯(lián)起來(早綁定)
動態(tài)聯(lián)編(動態(tài)鏈接) 在程序執(zhí)行的時候才將函數(shù)實現(xiàn)和函數(shù)調用關聯(lián)(晚綁定)——引入一個虛函數(shù)表實現(xiàn)
C++中一般情況下的聯(lián)編指靜態(tài)聯(lián)編,一旦涉及到多態(tài)和虛擬函數(shù)就必須使用動態(tài)聯(lián)編
重載只是一種語言特性,編譯器根據(jù)函數(shù)不同的參數(shù)表,把同名函數(shù)區(qū)分開來屬于靜態(tài)聯(lián)編,與多態(tài)無關。
—————————————————————————————————————————————————————————
Day 8
異常: 讓一個函數(shù)在發(fā)現(xiàn)了自己無法處理的錯誤時拋出(throw)一個異常,然后他的(直接或間接)調用者能夠處理這個問題。
異常處理機制是一種比較有效的處理系統(tǒng)運行時錯誤的方法。
在執(zhí)行程序發(fā)生異常時,可以不在本函數(shù)中處理,而是拋出一個錯誤信息,把它傳遞給上一級的函數(shù)來解決,上一級解決不了再傳遞給上一級,一直直到最高一層還無法處理的話,運行系統(tǒng)會自動調用系統(tǒng)函數(shù)terminate,由他調用abort終止程序。
異常處理——try(檢查)——》throw(拋出)——》catch(捕獲)
自定義異常 設計程序時會自定義很多錯誤,這些錯誤在標準錯誤里是沒有的,所以我們往往需要自定義很多異常類。
自定義異常可以從標準異常exception類派生出來 也可以完全自定義一個異常類。
在定義的異常函數(shù)后必須加上空異常的關鍵字——因為異常函數(shù)自身需要嚴格定義不允許異常函數(shù)有異常報出。(通用 throw() 空異常 高版本用 nothrow關鍵字)
轉換函數(shù):
Int val = 0;
Char ch = ‘a’;
Int main (int argc, char *argv[])
{
Val = ch; //隱式轉換
Ch = char(val) // 顯式轉換
}
轉換函數(shù)的實質為運算符重載,只是重載的運算符不是內置的運算符而是類
Operator 類型名()
{
實現(xiàn)轉換的語句
}
規(guī)則——轉換函數(shù)只能是成員函數(shù),無返回值,空參數(shù)
不能定義為void的轉換,也不允許轉換成數(shù)組或者函數(shù)類型
轉換常定義為const形式,(轉換函數(shù)并不改變數(shù)據(jù)成員的值)
Explicit關鍵字—— 修飾類的構造函數(shù),被修飾的構造函數(shù)的類,不能發(fā)生相應的隱式類型轉換
給單參數(shù)的構造函數(shù)使用explicit關鍵字,阻止可能產生的隱式轉換:由成員變量類型轉換為類類型

