C++ 進階篇

指針數組
數組的元素是指針類型
Point *pa[2];
指針數組與二維數組的差別
指針數組的元素在內存中不一定連續(xù)呵哨,二維數組中的元素在內存中也是連續(xù)存放的
指針數組與二維數組的相同點 :邏輯上相鄰

指針作為函數參數
優(yōu)點
1.可以實現數據的雙向傳遞(引用也可以)
2.需要傳遞一組數據或對象時 只傳首地址運行效率高(如果不想傳遞的值被修改甥郑,那么可以使用const type& || const type*)

指針類型的函數
函數返回類型是指針類型
不要將非靜態(tài)的局部地址用作函數的返回值(因為出了這個作用域這個對象就消亡了航瞭,內存空間被釋放掉了)用new動態(tài)創(chuàng)建的對象不會自動消亡携茂,必須要使用delete 關鍵字進行釋放,否則會內存泄漏

指向函數的指針
函數指針指向的程序代碼儲存區(qū) 也就是函數的首地址
定義形式
返回值類型 (函數名)(參數列表)
int (
func)(int,int)
指向函數的指針用途:把函數當參數傳(也就是C#中的委托)

對象指針
point *a;
對象指針訪問數據 a->data 語法上等同于 *(a).data;

this指針
隱含于類的非靜態(tài)成員函數中
指出成員函數所操作的對象
當通過一個對象調用成員函數時雕蔽,系統(tǒng)首先將該對象的地址賦給this指針折柠,然后調用成員函數,成員函數對對象的數據成員進行操作時批狐,就隱含使用了this指針

動態(tài)內存內配
動態(tài)申請內存操作符 new
new 類型名T(初始化參數列表)
分配成功返回T類型的指針扇售,指向新分配的內存首地址,失敗就拋出異常

釋放內存
delete 指針p
釋放指針p指向的內存 p必須是new 操作的返回值

動態(tài)申請數組
Point *p = new Point[2]; //數組訪問元素 p[0]
釋放動態(tài)數組
delete[] p; //記得寫括號,不然只釋放數組的首元素

動態(tài)多維數組
char (*cp)[3]; //表示定義了一個指向包含3個元素的一維數組的指針 cp指向數組的首地址
cp = new char[2][3] // cp指向首地址第一行 *(cp+1) = 數組的第二行

vector對象
封裝任何類型的動態(tài)數組承冰,自動創(chuàng)建和刪除
數組下標越界檢查

vector 對象使用
vector<元素類型> 數組對象名(數組長度)
vector<int> arr = {1,2,3}
v.begin() 獲得頭元素(迭代器)
v.end(); 最后一個元素

深層復制于淺層復制
淺層復制是將對象中的所有值都拷貝到復制的對象中嘱根,當對象中有指針時,此時兩個對象指針指向同一內存區(qū)域巷懈,導致出現問題
深層復制,將對象或數組重新分配內存慌洪,然后將對象中的值復制過去顶燕,若對象中還有對象,那么繼續(xù)執(zhí)行深層復制

移動構造 (C++11新標準)
移動語義:源對象資源的控制權全部交給目標對象
classname(classname &&)
&& 右值引用 即將消亡的值就是右值 函數返回的值也是右值

C風格字符串
用字符數組來存放字符串
末位填 /0

string
構造string常用的構造函數
string();
string s1;
string(const char *s);
string s2 = "abc";
string(const string& s);
string s3 = s2;

輸入整行字符串
getline() //要包括string頭文件
getline(cin,s2) //從鍵盤讀取數據冈爹,并保存到s2中
getline(cin,s2,',')//使用其他分隔符作為字符串結束的標志涌攻,第三個參數指定分隔符
兩個參數的getline() 默認以換行符進行結束

繼承
吸收基類成員 除構造函數于析構函數外所有成員
C++ 11中規(guī)定可以使用using語句繼承基類構造函數

三種繼承方式

公有繼承
基類成員在子類中 pubilc protected 訪問屬性不變, private 不可直接訪問
成員函數可以直接基類成員中 pubilc protected ,不可訪問private,
派生的對象只能訪問基類中public成員

私有繼承
基類成員在子類中 pubilc protected 訪問屬性變成private频伤, private 不可直接訪問
成員函數可以直接訪問基類成員中的 pubilc protected ,不可訪問private,
派生的對象不能訪問中基類中任何成員

保護繼承
基類成員在子類中 pubilc protected 訪問屬性變成protected恳谎, private 不可直接訪問
成員函數可以直接基類成員中 pubilc protected ,不可訪問private,
派生的對象不能訪問中基類中任何成員

usingB : B //使用using 繼承基類構造函數

若不繼承基類構造函數
派生類新增成員:派生類定義構造函數進行初始化
繼承來的成員:自動調用基類的構造函數進行初始化
派生類的構造函數需要給基類的構造函數傳遞參數

單繼承時構造函數定義語法
派生類名::派生類名(基類所需形參,本類中所需形參):基類名(參數表)憋肖,本類初始化列表
{
其他初始化
}

多繼承時構造函數定義語法
派生類名::派生類名(參數表):
基類名1(基類1初始化參數列表)因痛,
基類名2 (基類2初始化參數列表),
本類成員初始化列表
{
其他初始化
}

構造函數調用順序
1.調用基類的構造函數 (按被繼承的先后順序調用)
2.對初始化列表中的成員進行初始化(順序按照在類中定義的順序,對象成員初始化自動調用其所屬類的構造函數 由初始化列表傳遞參數)
3.執(zhí)行派生類中構造函數體中的內容

派生類的復制構造函數

class A : class B
{
  //派生類沒有自己實現復制構造函數的時候岸更,調用派生類復制構造的時候鸵膏,會主動調用基類復制構          
  //造函數
  //自己實現復制構造函數的時候,需要給基類的復制構造函數傳參
  A(const &A):B(A)  //直接用派生類對象傳遞給基類復制構造函數
}

構造函數調用順序
先調用基類的構造函數怎炊,然后調用派生類的構造函數

派生類的析構函數
調用順序與構造時相反
先調用派生類的析構函數 谭企,然后調用基類的析構函數

派生類和基類中有相同成員
若無特別限定,則通過派生類對象訪問的是派生類中的成員
若需要訪問基類成員评肆,則需要 基類名::成員名 訪問基類成員
派生類.基類名::成員名 or 派生類指針->基類名::成員名

虛基類


C++中菱形繼承.png

菱形繼承產生冗余债查,并有可能因冗余帶來不一致性
菱形繼承雖然可以通過限定符消除二義性,但帶來上存儲空間上的浪費瓜挽,對于一個類繼承了兩次

使用虛基類可以解決這個問題
對最遠的派生類提供唯一的基類成員盹廷,而不重復產生多次復制
需要在第一級繼承時就要設計共同基類為虛基類

虛基類的格式

class A:virtual public B  //(virtual 關鍵字)
{
  A():B(param);
}

虛基類的問題
虛基類的成員需要由最遠派生類的構造函數通過調用虛基類的構造函數進行初始化
在整個結構中,只要繼承了虛基類的派生類秸抚,都需要在構造函數中為虛基類列出參數
如果沒有列出速和,那么默認調用該虛基類無參的構造函數
在建立對象時,只有最遠派生類的構造函數調用虛基類的構造函數剥汤,其他類對虛基類構造函數的調用被忽略(寫要寫颠放,調用只以當前創(chuàng)建對象的所屬類來調用)

運算符重載
運算符重載可以有兩種實現方式 1.類中成員函數 2.類外全局函數
運算符重載關鍵字 operator , 運算符重載依靠函數實現

雙目運算符重載
Clock Clock::operator + (const Clock& c)

單目運算符重載
前置++重載 返回左值
Clock& Clock::operator ++();
//后置++ 返回右值 后置需要一個int類型的形參作為區(qū)分前置還是后置
Clock Clock::operator ++(0)

非成員函數的重載形式
Clock operator+(Clock &c1,Clock &c2)

虛函數
虛函數關鍵字virtual 給函數加上virtual 關鍵字 給編譯器標識,編譯器在靜態(tài)綁定時不考慮此函數
實現動態(tài)綁定
虛函數需要實現動態(tài)綁定吭敢,則虛函數不能實現為內聯(lián)函數碰凶,因為內聯(lián)函數為靜態(tài)綁定,編譯階段就需要處理,二者矛盾欲低,所以虛函數不能為內聯(lián)函數
虛函數屬于對象辕宏,虛函數必須是非靜態(tài)的成員函數
構造函數不能為虛函數,析構函數可以為虛函數

虛析構函數
在使用繼承時砾莱,若基類指針使用運動時多態(tài)釋放對象操作時瑞筐,若析構函數不是虛函數,則會出現靜態(tài)綁定腊瑟,只調用基類的析構函數聚假,而沒有調用派生類的構造函數,此時需要將基類的析構函數定義為虛析構函數闰非,進一步正確使用動態(tài)綁定釋放資源膘格,否則會內存泄漏


例子.png

虛表與動態(tài)綁定
動態(tài)綁定的實現機制


虛表.png

沒個含有虛函數的對象,內部都包含一個指向虛表的指針vptr
若B繼承A , A 對象指向A對象的虛函數 B對象指向B對象的虛函數财松,若B中沒有實現A中的某虛函數瘪贱,則B對象的該函數就指向父類的虛函數

抽象類
純虛函數 是在基類中定義的虛函數,它在基類中沒有定義具體的操作內容辆毡,要求派生類根據自己的實際需要定義自己的版本
virtual 函數類型 函數名(參數表)= 0 ;//等于零表示沒有函數體
帶有純虛函數的類就是抽象類
抽象類無法實例化
派生類沒有實現純虛函數時菜秦,派生類也是純虛函數類,也無法實例化舶掖,只有完成了對純虛函數的實現喷户,才可以實例化

OVERRIDE C++11新標準
顯示函數覆蓋
好處是 編譯器會介入檢查,使用了OVERRIDE后访锻,會在基類中找同樣的原型的虛函數
若找不到褪尝,編譯器會進行報錯

FINAL C++11新標準
FINAL 關鍵字 在類中使用,表示該類不能被繼承
FINAL 關鍵字 在函數中使用 表示該函數不能被覆蓋(重寫)
Class A final {}
virtual void f() final

函數模板
template<class T > //作用就是與C#中的泛型

類模板
template<class T> //只能在頭文件中寫
class className<T>{}
類模板中的成員函數
返回值類型 className<T>::functionName(param);

STL簡介
STL 標準模板庫(Standard Template Libary)定義了一套概念期犬,為泛型程序設計提供了邏輯結構

STL基本組件
1.容器
2.迭代器
3.函數對象
4.算法

IO流

輸出流對象 ofstream
構造輸出流對象ofstream

ofstream myFile("filename"); //指定文件名 默認打開

ofstream myFile;
myFile.open("filename") //構造函數不給文件名參數河哑,可以使用open與文件建立關系

打開文件可以指定模式
ofstream myFile("filename",ios_base::out | ios_base::binary); //可以使用多種模式 使用多種時用按位或運算符

其他函數
put函數 //把一個字符寫到輸出流中
write函數 //把內存中的一塊內容寫到一個文件輸出流中 二進制
close函數 //關閉一個文件輸出流關聯(lián)的磁盤文件
seekp 函數 //移動寫指針
tellp 函數 //返回當前寫指針位置

操縱符
流寬度
setw(n) //設置輸出流對象cout 的輸出所占字符 只影響后續(xù)字符 cout<<setw(1)<<n<<endl; 表示n只占一個字符的輸出位置

setiosflags 流格式標識
定義在iomanip頭文件中
setiosflags(ios_base::left) //設置對齊方式,影響后續(xù)所有字符 cout<<setiosflags(ios_base::left) //后續(xù)字符全部左對齊
resetiosflags(ios_base::left) //取消左對齊
setiosflags 可以使用 | 進行組合

精度 setprecision
在定點數格式 fixed 與科學計數法 下 精度表示為小數點后多少位
在其他情況下 參數表示有效數字位數 系統(tǒng)會根據數字大小 自動選擇fixed 方式龟虎,或者科學計數法方式
setprecision(精度)

臨時地址轉換
reinterpret_cast
Date dt = {6,10,12};
reinterpret_cast<char *> (&dt);// 臨時將dt地址轉換為char 類型的指針

二進制文件流
ofstream file("date.dat",ios_base::binary) //二進制形式
file.write(reinterpret_cast<char *> (&dt),sizeof(dt));
file.close();

字符串輸出流 (寫)
ostringstream 用于構造字符串
可以將其他類型轉換為字符串
支持ofstream 中除open璃谨,close 外的所有操作
str函數可以返回已經構造好的字符串

輸入流類 (從文件中讀)
istream 適合順序文本模式輸入 cin是其實例
ifstream類支持磁盤文件輸入
istringstream

構造輸入流類
ifstream myFile("filename"); //有參數 默認為打開此文件
ifstream myFile(); myFile.open("filename");// 與上述一致
打開文件時 也可以使用打開模式

字符串輸入流
istringstream
支持istream中除open,close外的所有操作
可將字符串轉化為數值

fstream 與 stringstream 都是由兩個邏輯子流構成 可以交替讀寫

異常處理
throw type //拋出異常

try
{
//捕獲異常
//捕獲到異常,則后續(xù)代碼不會執(zhí)行
}
catch(exception e)
{
//異常處理鲤妥,匹配異常類型佳吞,進入匹配的catch代碼段
}

異常接口聲明
可以在函數聲明時列出這個函數可能拋擲的所有異常類型
void fun() throw(A,B,C,D)
沒有異常接口聲明,則可以拋出任意類型的異常
void fun() throw(); //列表為空棉安,表示不拋出任何異常

異常處理中的構造與析構
自動析構
在try塊中 創(chuàng)建的對象底扳,由于發(fā)生了異常,導致后續(xù)代碼不執(zhí)行贡耽,創(chuàng)建的對象沒有析構衷模,按理說會造成內存泄漏
找到匹配catch塊后鹊汛,會從try塊開始到異常被拋擲處之間構造的所有對象自動進行析構

標準異常類繼承關系圖.png
標準異常類含義.png

exception 標準程序庫中異常類的公共基類(所有異常的爸爸)
logic_error 表示可以在程序中被預先檢測到的異常
runtime_error 表示難以被預先檢測到的異常

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阱冶,隨后出現的幾起案子刁憋,更是在濱河造成了極大的恐慌,老刑警劉巖木蹬,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件至耻,死亡現場離奇詭異,居然都是意外死亡镊叁,警方通過查閱死者的電腦和手機有梆,發(fā)現死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來意系,“玉大人,你說我怎么就攤上這事饺汹』滋恚” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵兜辞,是天一觀的道長迎瞧。 經常有香客問我,道長逸吵,這世上最難降的妖魔是什么凶硅? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮扫皱,結果婚禮上足绅,老公的妹妹穿的比我還像新娘。我一直安慰自己韩脑,他們只是感情好氢妈,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著段多,像睡著了一般首量。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上进苍,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天加缘,我揣著相機與錄音,去河邊找鬼觉啊。 笑死拣宏,一個胖子當著我的面吹牛,可吹牛的內容都是我干的杠人。 我是一名探鬼主播蚀浆,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼缀程,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了市俊?” 一聲冷哼從身側響起杨凑,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摆昧,沒想到半個月后撩满,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡绅你,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年伺帘,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忌锯。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡伪嫁,死狀恐怖,靈堂內的尸體忽然破棺而出偶垮,到底是詐尸還是另有隱情张咳,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布似舵,位于F島的核電站脚猾,受9級特大地震影響,放射性物質發(fā)生泄漏砚哗。R本人自食惡果不足惜龙助,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛛芥。 院中可真熱鬧提鸟,春花似錦、人聲如沸仅淑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漓糙。三九已至铣缠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昆禽,已是汗流浹背蝗蛙。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留醉鳖,地道東北人捡硅。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像盗棵,于是被迫代替她去往敵國和親壮韭。 傳聞我的和親對象是個殘疾皇子北发,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內容