C程序設(shè)計(jì)基礎(chǔ)教程_第1頁
C程序設(shè)計(jì)基礎(chǔ)教程_第2頁
C程序設(shè)計(jì)基礎(chǔ)教程_第3頁
C程序設(shè)計(jì)基礎(chǔ)教程_第4頁
C程序設(shè)計(jì)基礎(chǔ)教程_第5頁
已閱讀5頁,還剩341頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第二期更新內(nèi)容C++11/14標(biāo)準(zhǔn)Lambda、static_assert,typetraits,Movesemantics。。。WIN32消息,繪圖,控件,資源,文件,內(nèi)存,進(jìn)程,線程。。。當(dāng)前1頁,總共346頁。起源語言特點(diǎn)語言缺點(diǎn)C++語言及相關(guān)軟件介紹day01前景與方向編譯器安裝與配置

當(dāng)前2頁,總共346頁。由C++起源:1974年Bjarne博士在分析與研究UNIX系統(tǒng)由與內(nèi)核分布面造成的網(wǎng)絡(luò)流量時試圖尋找一種有效工具使其更加模塊化他在c的增加了類似Simula的類的機(jī)制并與1983年開發(fā)一種新的語言C++;當(dāng)前3頁,總共346頁。C++的語言特點(diǎn)1兼容c且繼承了c的特性

并同c一樣高效且可移植2屬于面向?qū)ο蟮木幊?/p>

抽象封裝繼承多態(tài)3語言靈活(類的層次結(jié)構(gòu)設(shè)計(jì))且支持指針3支持運(yùn)算符重載4異常處理機(jī)制5支持泛型編程Tf(Tx){returnx*x;}6多種類庫的支持

當(dāng)前4頁,總共346頁。語言缺點(diǎn):

語言復(fù)雜

支持多種設(shè)計(jì)風(fēng)格

復(fù)雜的c++程序正確性不易保證C++的發(fā)展方向windows平臺unix平臺

嵌入式當(dāng)前5頁,總共346頁。C++也是一種編譯型的語言推薦使用vs2013編譯環(huán)境其他可選vc6.0vs2010nodepad++vs2013基本支持c11標(biāo)準(zhǔn)vs2010以上Vs2013是微軟公司的一款軟件開發(fā)平臺IDE(集成開發(fā)環(huán)境)Vs2013的安裝使用1安裝前需要先安裝IE10提供支持2下載安裝包/s/1qW2NM0k2.81G(中文版本)3打開安裝包選擇安裝位置如下:當(dāng)前6頁,總共346頁。當(dāng)前7頁,總共346頁。4安裝vs2013當(dāng)前8頁,總共346頁。5安裝完成(20分鐘左右)當(dāng)前9頁,總共346頁。如何建立一個c++程序文件->新建->(visualc++類型)+win32consoleapplication

自定義文件名文件路徑->應(yīng)用程序設(shè)置->其他選項(xiàng)->空工程->源文件->新建條目->c++文件->添加->完成當(dāng)前10頁,總共346頁。當(dāng)前11頁,總共346頁。C++的頭文件名字空間簡單的i/0函數(shù)一個簡單的c++程序day02C++風(fēng)格的操作當(dāng)前12頁,總共346頁。Vs2013基本設(shè)置行號設(shè)置:

工具-選項(xiàng)-文本編輯器-所有語言-行號選中快捷鍵:

1復(fù)制:如果你想復(fù)制一整行代碼,只需將光標(biāo)移至該行,再使用組合鍵

“Ctrl+C”來完成復(fù)制操作,而無需選擇整行2剪切:如果你想剪切一整行代碼,只需將光標(biāo)移至該行,再使用組合鍵

“Ctrl+X”來完成剪切操作,而無需選擇整行。

當(dāng)前13頁,總共346頁。3刪除:如果你想刪除一整行代碼,只需將光標(biāo)移至該行,再使用組合鍵

“Ctrl+L”來完成剪切操作,而無需選擇整行。4粘貼:如果你想粘貼你已經(jīng)復(fù)制的內(nèi)容將光標(biāo)移至該行再使用組合鍵

“Ctrl+v”來完成粘貼操作5撤銷:使用組合鍵“Ctrl+Z”進(jìn)行撤銷操作;6反撤銷:使用組合鍵“Ctrl+Y”進(jìn)行反撤銷操作。7查找:Ctrl+f(Ctrl+H替換)8移動光標(biāo):home行首end行尾當(dāng)前14頁,總共346頁。調(diào)試相關(guān)1)調(diào)試(啟動):F5;(調(diào)試器)2)ctrl+s保存修改4)調(diào)試(逐語句):F11;5)調(diào)試(逐過程):F10;6)設(shè)置斷點(diǎn):F9。7)調(diào)試不執(zhí)行:F7當(dāng)前15頁,總共346頁。1創(chuàng)建源文件c++的源文件的擴(kuò)展名使用:.cpp.cc.C.cxx2#include<iostream>

為c++標(biāo)準(zhǔn)庫的i/o函數(shù)的頭文件

c++舊式風(fēng)格:iostream.hc++新式風(fēng)格:iostreamcstring3usingnamespacestd;using編譯指令指定使用的名字空間namespacestd標(biāo)準(zhǔn)名字空間

當(dāng)前16頁,總共346頁。4cin>>a;cout<<a<<endl;c++的輸入輸出的方式cout為一個對象c++沒有格式化字符串輸出但有相應(yīng)的格式化的控制符和流函數(shù)cout/cin還有明顯的優(yōu)點(diǎn):

類型識別功能可擴(kuò)展性(重定義<<運(yùn)算符支持各種數(shù)據(jù)類型)endl;控制符移動到光標(biāo)所在的下一行二c風(fēng)格的操作1#include<stdio.h>當(dāng)前17頁,總共346頁。

導(dǎo)入c頭文件#include<cstdio>#include”add.h”//h可以不加

其他庫函數(shù)包含對應(yīng)的頭文件正常使用

例:strcpy(a,b);編譯:

終端窗口:gccap1.cpp–lstdc++g++ap1.cppvs開發(fā)環(huán)境:F7相同

當(dāng)前18頁,總共346頁。當(dāng)前19頁,總共346頁。名字空間的引入定義使用名字空間day03嵌套無名名字空間

當(dāng)前20頁,總共346頁。名字空間的引入:

在C++中名稱可以是變量函數(shù)結(jié)構(gòu)體類及類的相關(guān)成員使用第三方類庫

時極有可能出現(xiàn)名稱沖突c++利用作用域的特性引入了名字空間的概念名字空間:名字空間是一種描述邏輯分組的機(jī)制send(sendEx)send{sendEx}

防止命名沖突跨文件訪問注意:名字空間可以是全局的可以是位于另一個名稱空間中不可以存在于代碼塊中當(dāng)前21頁,總共346頁。1定義:namespaceA{ intI; doubled;voidshow();}namespaceB{ intIfloatf;}

當(dāng)前22頁,總共346頁。A中的I與B中的I并不發(fā)生沖突2相同名字空間可以多次添加補(bǔ)充名字空間的內(nèi)容namespaceA{ show(){…….}};非用戶定義的名稱空間存在于全局命名空間

當(dāng)前23頁,總共346頁。intI;

使用:A::I=0;B::I=1;::I=2;//全局命名空間

::為作用域解析運(yùn)算符(域運(yùn)算符)

當(dāng)前24頁,總共346頁。1Using:為了避免每次都使用名字空間時都要其進(jìn)行名字空間限定

可以使用using對名字空間內(nèi)的內(nèi)容進(jìn)行特定區(qū)域的聲明usingA::I;//using聲明std::cout再次使用可以直接調(diào)用名稱而無需增加空間限定這種聲明可以全局全局域同名變量std::coutintInamespaceA{inti}main2using:作為編譯指令的使用使對應(yīng)名字空間內(nèi)的所有內(nèi)容可用且使用時可

以省略作用域解析運(yùn)算符usingnamespaceA;當(dāng)前25頁,總共346頁。

注意事項(xiàng):1避免歧義usingA::I;usingB::I;I=1;//??哪一個?2不要用using聲明相同名稱的內(nèi)容usingA::I;intI;3using做編譯指令時名稱空間為全局如果局部于名稱空間的

名字相同則局部覆蓋名字空間內(nèi)容namespace{externinti}4局部名稱會覆蓋全局與using指令的名字空間內(nèi)容但可以用I(局部)::I(全局)A::I(名字空間)區(qū)分使用5using聲明比using編譯安全當(dāng)前26頁,總共346頁。

聲明是指定具體內(nèi)容編譯器發(fā)出指示

編譯指令導(dǎo)入全部名字空間內(nèi)容可能發(fā)生沖突覆蓋時編譯器

不會發(fā)出警告當(dāng)前27頁,總共346頁。名字空間的嵌套NamespaceA{ inta;namespaceB{ intb;}}訪問:A::B::b=1;當(dāng)前28頁,總共346頁。未命名名字空間:內(nèi)部鏈接特性與static修飾的內(nèi)容特性相同Namespace{ inta;}cout<<a<<endl;補(bǔ)充:1Iostream相關(guān)函數(shù)存放在std的名字空間內(nèi)UsingStd::cout<<.當(dāng)前29頁,總共346頁。內(nèi)聯(lián)名字空間(c++11)關(guān)鍵字inline一種新的嵌套名字空間的使用方式嵌套在名字空間的內(nèi)聯(lián)名字空間在使用時不需其名字空間進(jìn)行限定使用Inlinenamespaceinspace{}當(dāng)前30頁,總共346頁。當(dāng)前31頁,總共346頁。布爾類型string類型結(jié)構(gòu)體數(shù)據(jù)類型day04聯(lián)合枚舉當(dāng)前32頁,總共346頁。1新的數(shù)據(jù)類型:布爾類型:bool表示布爾量的數(shù)據(jù)類型取值:由字面值常量true(非零)真false(‘\0’NULLfalse0)

構(gòu)成trueboolisok=true;boolnotok=false;2字面值truefalse可以通過提升轉(zhuǎn)換為int類型true1false0inta=true;//a=1;3任何基本類型都可以被隱式轉(zhuǎn)換為布爾類型

轉(zhuǎn)換后非0為真0為假當(dāng)前33頁,總共346頁。二String類型(類)(自動處理大小)使用需要添加頭文件stringC語言中是用字符數(shù)組來存放字符串chara1[10]=“abc”a2[2]={‘a(chǎn)’,’\0’};1初始化:stringstr1;stringstr2=“abc”;2String可以做賦值

拼接等功能

當(dāng)前34頁,總共346頁。結(jié)構(gòu)體:

在c++中結(jié)構(gòu)體內(nèi)允許定義函數(shù)且結(jié)構(gòu)體在計(jì)算大小時為1而C中為0

在定義結(jié)構(gòu)體時可以省略關(guān)鍵字struct聯(lián)合:定義時可以省略聯(lián)合名為匿名聯(lián)合()

訪問時可以不用加聯(lián)合的前綴X.枚舉:枚舉類型在c++中為一個獨(dú)立的類型不能把一個整數(shù)賦值給一個枚舉變量當(dāng)前35頁,總共346頁。C++11:1類型的占位符auto根據(jù)初始化的內(nèi)容推斷變量類型作用簡化代碼2nullptrstd::nullptr_t類型的值,用來指代空指針nullptr和任何指針類型以及類成員指針類型的空值之間可以發(fā)生

隱式類型轉(zhuǎn)換,同樣也可以隱式轉(zhuǎn)換為bool型.當(dāng)前36頁,總共346頁。強(qiáng)類型枚舉C++11中通過引入了一個稱為強(qiáng)類型枚舉的新類型,修正了這種情況。強(qiáng)類型枚舉由關(guān)鍵字enumclass標(biāo)識。它不會將枚舉常量暴露到外層作用域中,也不會隱式轉(zhuǎn)換為整形,并且擁有用戶指定的特定類型(傳統(tǒng)枚舉也增加了這個性質(zhì))當(dāng)前37頁,總共346頁。當(dāng)前38頁,總共346頁。函數(shù)重載(函數(shù)多態(tài))

重載機(jī)制啞元函數(shù)函數(shù)重載一day05當(dāng)前39頁,總共346頁。1概念:同一作用域的一組參數(shù)列表不同,函數(shù)名相同的函數(shù)這組函數(shù)叫

函數(shù)重載(C++允許定義相同名稱的函數(shù))

作用:

重載函數(shù)通常用來命名一組功能相似的函數(shù),這樣做減少了函數(shù)名的數(shù)量,

避免了名字空間的污染,對于程序的可讀性有很大的好處(一物多用)

參數(shù)列表不同:1參數(shù)類型不同2參數(shù)順序不同3參數(shù)個數(shù)不同

重載版本根據(jù)參數(shù)的匹配度進(jìn)行選擇當(dāng)前40頁,總共346頁。注意:1.1與函數(shù)參數(shù)的變量名無關(guān)1.2函數(shù)的返回值類型與重載無關(guān)2函數(shù)重載的實(shí)現(xiàn)原理是通過c++換名實(shí)現(xiàn)的extern“C”intfun()的形式可以以c的方式生成函數(shù)名(無換名機(jī)制)3使用場景:

當(dāng)函數(shù)基本上執(zhí)行相同的任務(wù)使用不同形式的數(shù)據(jù)時

當(dāng)前41頁,總共346頁。當(dāng)前42頁,總共346頁。啞元函數(shù)缺省參數(shù)內(nèi)聯(lián)函數(shù)函數(shù)重載二day06當(dāng)前43頁,總共346頁。啞元函數(shù):參數(shù)只有類型沒有形參名的函數(shù)voidfun(int);

功能:1保持向前兼容性2做函數(shù)的區(qū)分Toperator++(){}Toperator++(int){}

當(dāng)前44頁,總共346頁。缺省參數(shù)

如果函數(shù)的形參有缺省值,當(dāng)函數(shù)調(diào)用時沒有傳遞實(shí)參,那么形參就使用缺省值,如果調(diào)用函數(shù)時傳遞了實(shí)參,那么形參就使用實(shí)參的值

注意:1缺省參數(shù)靠右原則如果一個函數(shù)有多個參數(shù)且部分參數(shù)有缺省值那么缺

省值的參數(shù)必須靠右(在編譯期間確定參數(shù))2如果函數(shù)的聲明和定義分開那么缺省參數(shù)只能寫在函數(shù)的聲明部分3注意防止重載的沖突(歧義)4c++中函數(shù)的規(guī)則不接受任何參數(shù)(否則可能構(gòu)成重載)5凼數(shù)參數(shù)的缺省值叧能在凼數(shù)聲明丨指定當(dāng)前45頁,總共346頁。3內(nèi)聯(lián):函數(shù)使用關(guān)鍵字inline關(guān)鍵字修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù)

函數(shù)調(diào)用過程:調(diào)用用后立即存儲該指令的內(nèi)存地址

將函數(shù)參數(shù)復(fù)制到堆棧

跳到標(biāo)記函數(shù)起點(diǎn)的內(nèi)存單元執(zhí)行函數(shù)代碼(可能還有返回

值放入到寄存器中)

將返回值彈出

然后跳回到地址被保存的指令處

內(nèi)聯(lián)的實(shí)質(zhì):

就是把函數(shù)編譯好的二進(jìn)制代碼替換成函數(shù)的調(diào)用指令(省去了調(diào)用開銷)當(dāng)前46頁,總共346頁。(空間換取時間)注意:

1類中直接定義的函數(shù)自動被處理成內(nèi)聯(lián)函數(shù),所以一般把內(nèi)聯(lián)函數(shù)放在頭文

件中2inline是一種請求,實(shí)現(xiàn)方式取決于編譯器,特別是當(dāng)函數(shù)較大或是遞歸

的時候當(dāng)前47頁,總共346頁。當(dāng)前48頁,總共346頁。1引用的概念2如何創(chuàng)建一個引用3引用的本質(zhì)指針與引用day074引用的應(yīng)用5引用與指針當(dāng)前49頁,總共346頁。1引用:引用是已定義變量的別名,為c++新增的一種復(fù)合類型2創(chuàng)建一個引用:intvar_i;

int&revar_i=var_i;

注意:1這里的&不是取址符而是類型標(biāo)識符的一部分2創(chuàng)建引用時必需初始化3引用的內(nèi)容不能為空null4引用創(chuàng)建之后就不能更換引用的內(nèi)容int&ra=a;ra=b;

這樣定義之后我們就可以用var_i或rvar_i來操作變量var_i;

當(dāng)前50頁,總共346頁。3引用的本質(zhì):引用的內(nèi)部是由指針完成實(shí)現(xiàn)的int*double*

其本身并非一個實(shí)體類型(可由sizeof證明)int&double&4引用的應(yīng)用:4.1做函數(shù)的參數(shù)省去函數(shù)參數(shù)進(jìn)行復(fù)制時的內(nèi)存開銷

常引用型的參數(shù)可以防止實(shí)參被無意修改且可以接受常量型與

非常量型參數(shù)foo(constint&i){I=0}foo(a)4.2做函數(shù)的返回值做返回值時需保證返回值的有效性

注意:不能返回局部變量的引用

也可以返回常引用型的返回值

當(dāng)前51頁,總共346頁。補(bǔ)充:左值與非左值(右值)

一般的左值參數(shù)是可以被引用的數(shù)據(jù)對象如:變量數(shù)組元素結(jié)構(gòu)成員

引用和解除引用的指針都是左值

非左值包括字面常量(引號括起的字符串除外,它們由其地址表示)

和包含多項(xiàng)的表達(dá)式intI;I=10;10=I;strings1=s2+s3+s4;(a++)臨時變量temp(a+1),右值intc=(a+b)右值;“abc”=“abc”(++a)=1;左值int&&I=10;右值引用當(dāng)前52頁,總共346頁。5指針與引用5.1指針是一個實(shí)體存放地址而引用僅是一個內(nèi)存的別名5.2引用必須初始化且初始化后不可更換其引用的目標(biāo)

指針可以不初始化且其指針的指向的內(nèi)容可隨時更換(常指針除外)5.3引用不可以為空指針可以為空//char*pc=0;char&rc=*pc;..5.4引用的大小為所引用變量的大小指針為4個字節(jié)5.5因引用是一個內(nèi)存的別名所以不存在引用引用的引用和引用數(shù)組

但存在指向指針的指針和指針數(shù)組5.6在使用時,如果你的變量的指向可能發(fā)生變化或?yàn)榭?,請使用指針,?dāng)前53頁,總共346頁。如果你的變量不允許為空,可以引用5.7不存在空引用的事實(shí)意味著引用的代碼比指針的代碼效率要高(無需檢查其他合法性)5.8重載某些運(yùn)算符時,必須用到引用做返回值當(dāng)前54頁,總共346頁。當(dāng)前55頁,總共346頁。C語言的類型轉(zhuǎn)換C++的類型轉(zhuǎn)換Static_cast類型轉(zhuǎn)換day08Const_castReinterpret_cast當(dāng)前56頁,總共346頁。C++提供豐富的不同的數(shù)據(jù)類型當(dāng)不同類型在進(jìn)行算術(shù)運(yùn)算參數(shù)傳遞等一系列的操作時因計(jì)算機(jī)的特性不得不將不同的類型進(jìn)行轉(zhuǎn)換后再進(jìn)行操作1初始化和賦值進(jìn)行的轉(zhuǎn)換(int)dint(d)=右邊的類型將會轉(zhuǎn)換成左邊的數(shù)值類型(賦值后的數(shù)值不安全)2以{}方式初始化時進(jìn)行的轉(zhuǎn)換(不允許縮窄浮點(diǎn)轉(zhuǎn)換整型)(c++11)3表達(dá)式中的轉(zhuǎn)換

類型提升4傳遞參數(shù)時的轉(zhuǎn)換當(dāng)前57頁,總共346頁。5強(qiáng)制類型轉(zhuǎn)換5.1(typename)value:標(biāo)ctypename(value):c++5.2static_cast<目標(biāo)類型>(源類型變量)a->b

隱式類型轉(zhuǎn)換的逆轉(zhuǎn)換

轉(zhuǎn)換時做靜態(tài)檢查(在編譯時進(jìn)行)

檢查(諸如指針越界計(jì)算,類型檢查)Char->intIntchar當(dāng)前58頁,總共346頁。5.3const_cast<目標(biāo)類型>(源類型變量)去除指針或引用上的const屬性voidfoo(constint*i)5.4reinterpret_cast<目標(biāo)類型>(源類型變量)

任意類型的指針或引用或整型之間的轉(zhuǎn)換但不可改變const屬性

其他限制是不能轉(zhuǎn)換成比指針更小的類型不能將函數(shù)指針與其他

類型進(jìn)行轉(zhuǎn)換5.5dynamic_cast<目標(biāo)類型>(源類型變量)

多態(tài)父子類指針或引用之間的轉(zhuǎn)換動態(tài)轉(zhuǎn)換當(dāng)前59頁,總共346頁。當(dāng)前60頁,總共346頁。New的使用方法Delete使用方法Lambda表達(dá)式動態(tài)內(nèi)存分配/lambda表達(dá)式day09當(dāng)前61頁,總共346頁。C++在添加動態(tài)分配運(yùn)算符newdelete的同時,支持標(biāo)準(zhǔn)C的動態(tài)分配庫函數(shù)語法:1type_name*pointer_name=newtype_name;//未初始化

說明:與malloc不同new會根據(jù)類型的不同自動分配對應(yīng)的內(nèi)存大小

且返回對應(yīng)類型的指針2type_name*pointer_name=newtype_name(value)//初始化3type_name*pointer_name=newtype_name()//初始化為零4type_name*pointer_name=newtype_name[n]

分配n個type_name的數(shù)據(jù)的內(nèi)存大小當(dāng)前62頁,總共346頁。4type_name*pointer_name=newtype_name[n]={1,2,3,4..}c++0x標(biāo)準(zhǔn)初始化數(shù)組時進(jìn)行初始化5deletepointer_name與非new[]配對使用6delete[]pointer_name與new[]配對使用

某些編譯器在分配數(shù)組的大小時會在所分配的內(nèi)存前多加4個字節(jié)大小

用于存放分配的數(shù)組大小7對new分配內(nèi)存是否失敗的判斷new操作符會拋出bad_alloc異常當(dāng)前63頁,總共346頁。C++之父給C程序員的建議 1.1盡量的少使用宏使用inline函數(shù)替代帶參的宏使用constenum去替代常量宏 1.2使用namespace去避免命名沖突 1.3變量隨時用隨時定義以保證初始化 1.4盡量少使用強(qiáng)制類型轉(zhuǎn)換如果必須轉(zhuǎn)換就使用四個轉(zhuǎn)換運(yùn)算符中的一個1.5少使用mallocfree因?yàn)閚ewdelete會做的更好1.6盡量少使用C風(fēng)格的字符串因?yàn)閟tring會使用更方便1.7逐步建立面向?qū)ο蟮乃枷氘?dāng)前64頁,總共346頁。Lambda表達(dá)式”(lambdaexpression)是一個匿名函數(shù),即沒有函數(shù)名的函數(shù)。當(dāng)前65頁,總共346頁。Capture子句Lambda可在其主體中引入新的變量(用C++14),它還可以訪問(或“捕獲”)周邊范圍內(nèi)的變量。1.[var]表示值傳遞方式捕捉變量var;

2.[=]表示值傳遞方式捕捉所有父作用域的變量(包括this);

3.[&var]表示引用傳遞捕捉變量var;

4.[&]表示引用傳遞方式捕捉所有父作用域的變量(包括this);

5.[this]表示值傳遞方式捕捉當(dāng)前的this指針??誧apture子句[]指示lambda表達(dá)式的主體不訪問封閉范圍中的變量??梢允褂媚J(rèn)捕獲模式(標(biāo)準(zhǔn)語法中的capture-default)來指示如何捕獲lambda中引用的任何外部變量(使用capture-default時,只有l(wèi)ambda中提及的變量才會被捕獲)當(dāng)前66頁,總共346頁。注意事項(xiàng):引用捕獲可用于修改外部變量,而值捕獲卻不能實(shí)現(xiàn)此操作。(mutable允許修改副本,而不能修改原始項(xiàng)。)引用捕獲會反映外部變量的更新,而值捕獲卻不會反映。引用捕獲引入生存期依賴項(xiàng),而值捕獲卻沒有生存期依賴項(xiàng)。當(dāng)lambda以異步方式運(yùn)行時,這一點(diǎn)尤其重要。如果在異步lambda中通過引用捕獲本地變量,該本地變量將很可能在lambda運(yùn)行時消失,從而導(dǎo)致運(yùn)行時訪問沖突。當(dāng)前67頁,總共346頁。參數(shù)列表在C++14中,如果參數(shù)類型是泛型,則可以使用auto關(guān)鍵字作為類型說明符。這將告知編譯器將函數(shù)調(diào)用運(yùn)算符創(chuàng)建為模板。參數(shù)列表中的每個auto實(shí)例等效于一個不同的類型參數(shù)??勺円?guī)范通常,lambda的函數(shù)調(diào)用運(yùn)算符為const-by-value,但對mutable關(guān)鍵字的使用可將其取消。它不會生成可變的數(shù)據(jù)成員。利用可變規(guī)范,lambda表達(dá)式的主體可以修改通過值捕獲的變量當(dāng)前68頁,總共346頁。返回類型將自動推導(dǎo)lambda表達(dá)式的返回類型。無需使用auto

關(guān)鍵字,除非指定尾隨返回類型。trailing-return-type類似于普通方法或函數(shù)的返回類型部分。但是,返回類型必須跟在參數(shù)列表的后面,你必須在返回類型前面包含trailing-return-type關(guān)鍵字->。如果lambda體僅包含一個返回語句或其表達(dá)式不返回值,則可以省略lambda表達(dá)式的返回類型部分。如果lambda體包含單個返回語句,編譯器將從返回表達(dá)式的類型推導(dǎo)返回類型。否則,編譯器會將返回類型推導(dǎo)為void當(dāng)前69頁,總共346頁。Lambda體從封閉范圍捕獲變量,如前所述。參數(shù)本地聲明變量類數(shù)據(jù)成員(在類內(nèi)部聲明并且捕獲this時)具有靜態(tài)存儲持續(xù)時間的任何變量(例如,全局變量)當(dāng)前70頁,總共346頁。當(dāng)前71頁,總共346頁。面向?qū)ο蟪橄箢惻c對象類與對象day10當(dāng)前72頁,總共346頁。C++是一種面向?qū)ο蟮木幊陶Z言面向?qū)ο螅╫op)是一種特殊的設(shè)計(jì)程序的概念性方法C++的一些語言特性使得應(yīng)用這種方法更容易OPP特性:抽象封裝繼承多態(tài)代碼重用1抽象:現(xiàn)實(shí)空間邏輯抽象計(jì)算機(jī)

學(xué)生學(xué)生類STUDENT當(dāng)前73頁,總共346頁。學(xué)生:

屬性:stringname;stringmajor;doublescore;

行為:voidstudy();voidexam();voidplay();當(dāng)前74頁,總共346頁。2類:具有相同的屬性和行為的對象被分成一組即為一個類

類在c++中為一種自定義復(fù)合類型:成員變量成員函數(shù)(方法)3對象:類是對現(xiàn)實(shí)世界的抽象對象則是類在程序中的一個虛擬的實(shí)例可以用類來聲明變量(也稱為實(shí)例)。每個實(shí)例是類的一個對象4使用類來描述一個類struct/classSTUDENT{

訪問控制限定符://struct無 stringname;intstuID;

當(dāng)前75頁,總共346頁。 doublescore; voidstudy();voidexam();voidplay();}5實(shí)例化:定義類的實(shí)例可以稱為類的實(shí)例化 STUDENTstudent;6struct定義類成員默認(rèn)為公開class定義類成員默認(rèn)為私有當(dāng)前76頁,總共346頁。7成員控制限定符public:公有成員任意訪問protected:保護(hù)成員只有本類成員和子類可以訪問private:私有成員只有本類成員可以訪問

對不同成員的訪問控制屬性加以區(qū)分體現(xiàn)了c++作為面向?qū)ο蟪绦蛟O(shè)計(jì)語言的

封裝特性8類的聲明與實(shí)現(xiàn)可以分開(分開后則不能形成內(nèi)聯(lián))當(dāng)前77頁,總共346頁。當(dāng)前78頁,總共346頁。如何初始化對象創(chuàng)建過程對象的創(chuàng)建過程day11當(dāng)前79頁,總共346頁。如何初始化成員對象?(因?yàn)樗接谐蓡T的存在)C++為類的初始化提供了一個特有的函數(shù)--構(gòu)造函數(shù)構(gòu)造函數(shù)的作用:對對象的成員的初始化構(gòu)造函數(shù)的特性:1構(gòu)造函數(shù)與類型名相同2當(dāng)創(chuàng)建一個對象時會被自動調(diào)用(僅調(diào)用一次)3構(gòu)造函數(shù)沒有返回值類型4.1如果不提供構(gòu)造函數(shù)編譯器則自動提供一個無參構(gòu)造函數(shù)4.2但提供構(gòu)造函數(shù)編譯器會自動回收默認(rèn)的構(gòu)造函數(shù)4.3缺省構(gòu)造構(gòu)造對基本類型不做初始化類類型調(diào)用相應(yīng)的缺

當(dāng)前80頁,總共346頁。5構(gòu)造函數(shù)可以進(jìn)行重載6構(gòu)造函數(shù)的參數(shù)可以是默認(rèn)值,但默認(rèn)值必需靠右編寫一般可以通過構(gòu)造函數(shù)"參數(shù)的默認(rèn)值"簡化"構(gòu)造函數(shù)的個數(shù)"當(dāng)前81頁,總共346頁。–對象的創(chuàng)建過程1為整個對象分配內(nèi)存空間2以構(gòu)造實(shí)參調(diào)用構(gòu)造函數(shù)

2.1構(gòu)造基類部分(無基類忽略)

2.2構(gòu)造成員變量(如果是類類型則構(gòu)建這個成員)

2.3執(zhí)行構(gòu)造代碼(函數(shù)只放在代碼區(qū))3在棧中創(chuàng)建單個對象

類名對象;//注意不加空括號Aa;當(dāng)前82頁,總共346頁。類名對象(實(shí)參表)4在棧中創(chuàng)建對象數(shù)組

類名對象數(shù)組[元素個數(shù)]

類名對象數(shù)組[元素個數(shù)]={類名(實(shí)參表),,};

類名對象數(shù)組[]={類名(實(shí)參表),…};A*arr[10]=newA[10]{A(1),A(2)};實(shí)現(xiàn)一個時鐘類當(dāng)前83頁,總共346頁。當(dāng)前84頁,總共346頁。初始化列表類型轉(zhuǎn)換構(gòu)造拷貝構(gòu)造初始化列表,析構(gòu),單參構(gòu)造函數(shù)day12當(dāng)前85頁,總共346頁。1構(gòu)造函數(shù)的初始化列表A(inti):..i(i)..,.....{m_i=i;}與其他函數(shù)不同,構(gòu)造函數(shù)除了有名字,參數(shù)列表和函數(shù)體之外,還可以有初

始化列表,初始化列表以冒號開頭,后跟一系列以逗號分隔的初始化字段2為什么使用初始化列表初始化類的成員有兩種方式,一是使用初始化列表,二是在構(gòu)造函數(shù)體內(nèi)進(jìn)行

賦值操作//2.1常量成員,因?yàn)槌A恐荒艹跏蓟荒苜x值,所以必須放在初始化列表里面2.2引用類型,引用必須在定義的時候初始化,并且不能重新賦值,所以也要

寫在初始化列表里面當(dāng)前86頁,總共346頁。2.3成員變量的初始化順序:按照成員定義的順序進(jìn)行初始化(與初始化表的

順序無關(guān))2.4類的類型成員變量和基類子對象必須在初始化列表中初始化,否則將調(diào)用

相應(yīng)類型的缺省構(gòu)造函數(shù)進(jìn)行初始化(數(shù)組成員不能在列表中初始化)3類型轉(zhuǎn)換構(gòu)造函數(shù)(單參構(gòu)造函數(shù))

構(gòu)造函數(shù)當(dāng)其參數(shù)只有單個時它還有另一種功能:類型轉(zhuǎn)換3.1在目標(biāo)類型中,可以接受單個源類型對象實(shí)參的構(gòu)造函數(shù),支持從源類型

到目標(biāo)類型的隱式類型轉(zhuǎn)換classA{A(inti,intj=0,){}}Aa=100;3.2通過explicit關(guān)鍵字,可以強(qiáng)制這種通過構(gòu)造函數(shù)實(shí)現(xiàn)的類型轉(zhuǎn)換必須

顯式地進(jìn)行

當(dāng)前87頁,總共346頁。4析構(gòu)函數(shù)4.1析構(gòu)函數(shù)形式:~類名(){}4.2特點(diǎn):無返回值,無參數(shù),且不能重載4.3何時被調(diào)用:在銷毀對象時,會自動調(diào)用,且僅被調(diào)用一次

(也可手調(diào)用)4.4應(yīng)用:一般用于對對象在構(gòu)造過程或生命周期內(nèi)所申請的資源內(nèi)存

也可以執(zhí)行其他類設(shè)計(jì)者所需要的最后使用對象之后的操作

(如沒有動態(tài)分配內(nèi)存,非必需定義析構(gòu)函數(shù))4.5缺省析構(gòu)函數(shù)當(dāng)前88頁,總共346頁。5.1如果類中沒有定義析構(gòu)函數(shù),編譯器會提供一個缺省析構(gòu)函數(shù)5.2缺省析構(gòu)函數(shù)的特性:5.2.1對基本類型的成員變量不做任何操作5.2.2對類類型的成員變量和基類子對象,會調(diào)用相關(guān)的類型的析構(gòu)

函數(shù)6對象的銷毀過程6.1調(diào)用析構(gòu)函數(shù):執(zhí)行析構(gòu)函數(shù)

,析構(gòu)成員變量,析構(gòu)基類部分6.2釋放整個對象所占用的內(nèi)存空間當(dāng)前89頁,總共346頁。當(dāng)前90頁,總共346頁。This指針常對象This指針與const關(guān)鍵字day13當(dāng)前91頁,總共346頁。1this指針1.1概念:指向當(dāng)前對象類型的指針1.2構(gòu)造函數(shù)中this代表正在“被”構(gòu)建的對象的地址Aa;this=&a;1.3在成員函數(shù)中this代表調(diào)用這個函數(shù)的對象的地址

注意:Ithis是由編譯器自動產(chǎn)生的,在類的成員函數(shù)中有效IIthis是一個常量,不允許對其賦值。III當(dāng)在類的非靜態(tài)成員函數(shù)中訪問類的非靜態(tài)成員的時候,編譯器會

自動將對象本身的地址作為一個隱含參數(shù)傳遞給函數(shù)IVthis指針并不是對象本身的一部分,不會影響sizeof的結(jié)果

當(dāng)前92頁,總共346頁。2this指針的應(yīng)用2.1區(qū)分當(dāng)一個類的某個成員變量與該類構(gòu)造函數(shù)的相應(yīng)參數(shù)取相同標(biāo)識符,

在構(gòu)造函數(shù)內(nèi)部可以通過this指針將其區(qū)分2.2做函數(shù)的參數(shù)2.3做函數(shù)的返回值(串連調(diào)用)3常對象3.1概念:用const修飾的對象叫常對象3.2作用:被const修飾的對象的數(shù)據(jù)成員不可以被改變3.3格式:<類名>const對象名或const<類名>對象名當(dāng)前93頁,總共346頁。const<類名>*常對象指針名const<類名>&常對象引用名

注意:一常對象只能調(diào)用(常函數(shù)(不可在常函數(shù)內(nèi)修改成員變量,其實(shí)修飾

的是this指針,除非在成員函數(shù)被mutable(只能修飾成員變

量)))

二非常對象可以調(diào)用(常函數(shù))與(非常函數(shù))

三原型相同的成員函數(shù)的常版本與非常版本可構(gòu)成重載(匹配原則是:常對象只能選擇常版本

非常對象優(yōu)先非常版本)當(dāng)前94頁,總共346頁。常成員函數(shù)含義:通過該函數(shù)只能讀取同一類中的數(shù)據(jù)成員的值,而不能修改它常成員函數(shù)可不可以修改類外的變量?當(dāng)前95頁,總共346頁。當(dāng)前96頁,總共346頁。析構(gòu)函數(shù)靜態(tài)成員拷貝函數(shù)與靜態(tài)成員day14當(dāng)前97頁,總共346頁。4拷貝構(gòu)造函數(shù)

4.1函數(shù)形式:class類名{

類名(const類名&that){…}};4.2用于從一個已定義的對象構(gòu)造其同類型的副本Ab=a4.3如果一個類沒有定義拷貝構(gòu)造函數(shù),那么編譯器會為其提供一個缺省拷貝

構(gòu)造函數(shù)(淺拷貝)當(dāng)前98頁,總共346頁。4.3.1缺省拷貝對基本類型成員變量,按字節(jié)復(fù)制4.3.2缺省拷貝對類類型成員變量和基類子對象,調(diào)用相應(yīng)類型的拷貝構(gòu)造

函數(shù)4.3.3如果自己定義了拷貝構(gòu)造函數(shù),編譯器將不再提供缺省拷貝構(gòu)造函數(shù),

這時所有與成員復(fù)制有關(guān)的操作,都必須在自定義拷貝構(gòu)造函數(shù)中編

寫代碼完成(深拷貝)4.3.4若缺省拷貝構(gòu)造函數(shù)不能滿足要求,則需自己定義4.3.4拷貝構(gòu)造的時機(jī)

用已定義對象作為同類型對象的構(gòu)造實(shí)參當(dāng)前99頁,總共346頁。

以對象的形式向函數(shù)傳遞參數(shù)intfun(Ai);Ai=a;

從函數(shù)中返回對象

某些拷貝構(gòu)造過程會因編譯優(yōu)化而被省略

注:所有系統(tǒng)定義的構(gòu)造函數(shù),其訪問控制屬性均為公有(public) Aa;//二

靜態(tài)成員

static當(dāng)前100頁,總共346頁。7.1靜態(tài)成員屬于類而不屬于對象

//受類的訪問屬性限制的全局變量或函數(shù)

特性:1靜態(tài)成員變量不包含在對象實(shí)例中,生命期為整個程序2靜態(tài)成員函數(shù)無this指針與常屬性//3靜態(tài)成員與其他成員一樣受訪問控制的限制7.2靜態(tài)成員的定義與初始化

靜態(tài)成員只能在類的外部進(jìn)行初始化Aa1a2staticinti;7.3所有該靜態(tài)成員變量所屬的類的對象共有靜態(tài)成員7.4訪問屬性1靜態(tài)成員函數(shù)只能訪問靜態(tài)成員當(dāng)前101頁,總共346頁。2非靜態(tài)成員函數(shù)可以訪問靜態(tài)成員

也可以訪問靜態(tài)成員3不使用對象也可以直接使用靜態(tài)成員

靜態(tài)成員可以看成是受類的訪問屬性控制的全局變量或全局函數(shù)

當(dāng)前102頁,總共346頁。當(dāng)前103頁,總共346頁。設(shè)計(jì)模式:單例模式day15當(dāng)前104頁,總共346頁。一單例模式:一個類只有一個實(shí)例(任務(wù)管理器),而且自行實(shí)例化并向整個系

統(tǒng)提供這個實(shí)例(最常用,最簡單的模式)二根據(jù)實(shí)例化對象的時機(jī)的不同分為兩種:1餓漢式:程序啟動便創(chuàng)建實(shí)例//2懶漢式:調(diào)用時創(chuàng)建三優(yōu)點(diǎn):1內(nèi)存中只有一個實(shí)例,節(jié)約內(nèi)存2避免頻繁創(chuàng)建銷毀對象,提高性能3線程安全當(dāng)前105頁,總共346頁。當(dāng)前106頁,總共346頁。成員指針day16當(dāng)前107頁,總共346頁。1成員指針:是用于對類中成員進(jìn)行操作1.1定義格式:成員類型類名::*指針名=&類名::成員名intA::*pi;1.2使用形式:對象.*成員變量指針A*pa=newa;pa->*pi;

對象指針->*成員變量指針1.3與普通指針的區(qū)別:

普通指針用確定對象的地址進(jìn)行初始化,指向一個確定的對象

成員指針用類的成員(是類的成員,而不是對象的成員)初始化(其本

質(zhì)是記錄了特定成員變量在對象實(shí)例中的相對地址,再解引用時,根據(jù)

調(diào)用對象的地址計(jì)算出成員變量的絕對地址)當(dāng)前108頁,總共346頁。2成員函數(shù)指針2.1定義格式:

返回類型(類名::*成員函數(shù)指針)(形參表);

成員函數(shù)指針=&類名::成員函數(shù)名;2.2使用格式:(對象.*成員函數(shù)指針)(實(shí)參表)(對象指針->*成員函數(shù)指針)(實(shí)參表)2.3在調(diào)用成員函數(shù)指針時使用對象或?qū)ο笾羔樀脑蚴莻鬟fthis指針

當(dāng)前109頁,總共346頁。3靜態(tài)成員指針(與普通指針并沒有本質(zhì)區(qū)別只是多了類的防控屬性)3.1定義格式

類型*靜態(tài)成員變量指針

靜態(tài)成員變量指針=&類名::靜態(tài)成員變量3.2使用形式*靜態(tài)成員變量指針

返回類型(*靜態(tài)成員函數(shù)指針)(形參表);

靜態(tài)成員函數(shù)指針=類名::靜態(tài)成員函數(shù)名;

靜態(tài)成員函數(shù)指針(實(shí)參表)當(dāng)前110頁,總共346頁。當(dāng)前111頁,總共346頁。雙目運(yùn)算符友元二元操作符重載day17當(dāng)前112頁,總共346頁。1操作符重載概念:

在C++中,允許把已經(jīng)定義的有一定功能的操作符進(jìn)行重新定義,來完成更為

細(xì)致具體的運(yùn)算等功能,運(yùn)算符重載和函數(shù)重載都為簡單的一類多態(tài)2重載目的:c++的面向?qū)ο蟮某绦蛟O(shè)計(jì)需要依賴類的特性,運(yùn)算符重載的使用

使類類在使用普通運(yùn)算符時變的更加容易

3雙目操作符的表達(dá)式:L#Roperator#a+b

重載形式(成員函數(shù)):L.operator#(R)t1.operator+(TIME&t2){}L為調(diào)用對象,R為參數(shù)對象

重載形式(全局函數(shù)):::operator#(L,R)operator+(t1,t2);

當(dāng)前113頁,總共346頁。成員函數(shù)形式:

classLEFT{ LEFT&operator#(constRIGHT&right){…}};全局函數(shù)形式:LEFT&operator#(LEFT&left,constRIGHT&right){…}當(dāng)前114頁,總共346頁。4友元函數(shù)4.1通過關(guān)鍵字friend,可以將一個全局函數(shù),或另一個類的成員函數(shù),或

另一個類聲明為某一個類的友元B{friendA}4.2友元是一種定義在類外部的普通函數(shù),但它需要在類體內(nèi)進(jìn)行說明4.3友元函數(shù)可以訪問該類中的所有成員4.4友元函數(shù)不受類中訪問權(quán)限限制,把聲明放在類中哪里都可以4.5不是必要盡可能少用,因其破壞了面向?qū)ο蟮姆庋b性5友元類5.1如果類B的成員需要頻繁訪問類A的數(shù)據(jù)成員,但因?yàn)樵L控屬性的限制,當(dāng)前115頁,總共346頁。只能通過A的public函數(shù)進(jìn)行操作,那么可以將B聲明為A的友元類,這樣就可以訪問A中的未開放的數(shù)據(jù)成員5.2友元類

一個類可以做另一個類的友元類5.3聲明方式friendclass類名;5.4注意事項(xiàng)5.4.1友元關(guān)系是單向的5.4.2友元關(guān)系不能被傳遞5.4.3友元關(guān)系不能被繼承當(dāng)前116頁,總共346頁。當(dāng)前117頁,總共346頁。自增運(yùn)算符輸入輸出運(yùn)算符一元操作符重載day18當(dāng)前118頁,總共346頁。1單目操作符表達(dá)式:#o/o#2重載形式2.1重載形式(成員函數(shù)):O.operator#()a.operator+(b)2.2重載形式(全局函數(shù)):::operator#(O)a++;2.3前自增減(操作數(shù)為左值,表達(dá)式的值為左值,且為操作數(shù)本身)classA{//成員函數(shù)形式A&operator#(void){…}};Integeri1;++i1;A&operator#(A&a){…}//全局函數(shù)形式當(dāng)前119頁,總共346頁。2.4后自增減(操作數(shù)為左值,表達(dá)式的值為右值,且為自增減以前的值)classA{//成員函數(shù)形式 constAoperator#(int){…}};constAoperator#(A&a,int){…}//全局函數(shù)形式2.5輸出操作符:<<(左操作數(shù)為左值的輸出流對象,右操作數(shù)為左值或右值,

表達(dá)式的值左操作數(shù)本身)cout<<student<<endl;

如果重載以成員函數(shù)形式重載操作符,左操作ostream類為標(biāo)準(zhǔn)庫提供且無

法添加新成員,那么只能以全局形式重載該操作符

當(dāng)前120頁,總共346頁。重載形式(全局函數(shù)):ostream&operator<<(ostream&os,constRIGHT&right){…}2.6輸入操作符:>>(左操作數(shù)為左值的輸入流對象,右操作數(shù)為左值,表達(dá)

式的值左操作數(shù)本身)

如果重載以成員函數(shù)形式重載操作符,左操作istream類為標(biāo)準(zhǔn)庫提供且無

法添加新成員,那么只能以全局形式重載該操作符

istream&operator>>(istream&is,RIGHT&right){…}當(dāng)前121頁,總共346頁。當(dāng)前122頁,總共346頁。其他運(yùn)算符重載day19當(dāng)前123頁,總共346頁。1操作符重載限制1.1無法重載的運(yùn)算符:

作用域限定符(::)

成員運(yùn)算符(.)

直接成員指針解引用運(yùn)算符(.*.->)

條件運(yùn)算符(?:)

字符長度操作符(sizeof)

類型信息運(yùn)算符(typeid)

強(qiáng)制類型轉(zhuǎn)換運(yùn)算符(const_cast…)

當(dāng)前124頁,總共346頁。1.2重載限制重載后無法改變運(yùn)算符的優(yōu)先級與操作數(shù)的個數(shù)

不能重載非c++內(nèi)置的運(yùn)算符$newdeletenew[]delete[]

當(dāng)前125頁,總共346頁。當(dāng)前126頁,總共346頁。智能指針day20當(dāng)前127頁,總共346頁。1智能指針的概念:是對變通指針進(jìn)行類的封裝,當(dāng)智能指針離開作用域時,利

用類的機(jī)制對內(nèi)部的普通指針指向的內(nèi)存進(jìn)行管理foo(){PA(newA())}2作用://內(nèi)置類型auto_ptr<C>pa(newA)share_ptrpa->m_i;

相對于普通指針,當(dāng)其離開作用域時指針本身將會釋放,但指針指向的內(nèi)

存卻因?yàn)橹羔樀尼尫哦鵁o法得到釋放,而造成內(nèi)存泄漏。

智能指針是封裝了普通指針的類類型的對象,當(dāng)其離開作用時自動執(zhí)行的

析構(gòu)函數(shù)負(fù)責(zé)了對普通指針指向的內(nèi)存的釋放3智能指針與普通指針的比較3.1智能指針重載了“*”,“->”運(yùn)算符;當(dāng)前128頁,總共346頁。3.2一個對象只能有一個指向它的智能指針,而普通指針可以是多個3.3智能指針在做賦值時是以轉(zhuǎn)義的形式實(shí)現(xiàn)(非深/淺拷貝賦值)3.3智能指針不能用于對象的數(shù)組autoptrAa=bPointerA{ A&operator* A*operator-> return&**this;(**this==A)(&A==A*pa)pa->m_i;}當(dāng)前129頁,總共346頁。當(dāng)前130頁,總共346頁。概念語法繼承方式繼承day21訪控屬性當(dāng)前131頁,總共346頁。1面向?qū)ο蟮奶卣鳎悍庋b,繼承,多態(tài)2封裝:也就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只

讓可信的類或者對象操作,對不可信的進(jìn)行信息隱藏3繼承:可以使用現(xiàn)有類的所有功能,并在無需重新編寫原來的類的情況下對這

些功能進(jìn)行擴(kuò)展(類之間是is-a(kindof)的關(guān)系)4基類與派生類:4.1基類(父類):被繼承的類4.2派生類(子類):繼承數(shù)據(jù)的類5繼承的作用:當(dāng)前132頁,總共346頁。5.1代碼復(fù)用5.2功能擴(kuò)展6語法class子類:繼承方式1基類1,繼承方式2基類2…{…};7繼承方式

公有繼承:public

私有繼承:private

保護(hù)繼承:protected

8公有繼承的基本特點(diǎn)

當(dāng)前133頁,總共346頁。8.1訪問屬性:a子類中可以直接訪問基類的所有公有和保護(hù)成員b子類中不可以直接訪問基類的私有成員8.2名字隱藏:如果子類中有與基類中的公有或保護(hù)名字相同的成員,那么

子類的名字或隱藏所有基類中的同名成員

如果使用子類或通過子類訪問基類的被子類隱藏的成員可以

利用::進(jìn)行調(diào)用

9繼承方式與訪問控制

因?yàn)樽宇惖睦^承方式的不同,子類對訪問基類時的訪問控制屬性也會發(fā)生變化當(dāng)前134頁,總共346頁。基類中公有子類保護(hù)子類私有子類--------------------------------------------------公有成員公有成員保護(hù)成員私有成員保護(hù)成員保護(hù)成員保護(hù)成員私有成員私有成員私有成員私有成員私有成員注意:1子類訪問基類成員的最大的權(quán)限<=父類的權(quán)限2父類的私有數(shù)據(jù)到子類之后總是隱藏屬性3classsub:base{};默認(rèn)繼承方式為私有繼承//相對于類外,子類中的基類子對象,基類中的私有成員在子類中是不可見當(dāng)前135頁,總共346頁。當(dāng)前136頁,總共346頁。繼承中的構(gòu)造與析構(gòu)day22當(dāng)前137頁,總共346頁。1.1子類構(gòu)造函數(shù)隱式調(diào)用基類構(gòu)造函數(shù)

子類中的構(gòu)造函數(shù)沒有顯式指明基類部分的構(gòu)造方式,編譯器會選擇基類的

缺省構(gòu)造函數(shù)來構(gòu)造該子類中的基類子對象:1.2子類構(gòu)造函數(shù)顯式調(diào)用基類構(gòu)造函數(shù)

子類的構(gòu)造函數(shù)可以在初始化列表中顯式的指明基類部分的構(gòu)造方式1.3子類對象的構(gòu)造過程

構(gòu)造基類子對象->構(gòu)造本類成員變量->執(zhí)行構(gòu)造代碼1.4阻斷繼承:子類在構(gòu)造基類子對象時無論如何都要調(diào)用基類中的構(gòu)造函數(shù),

如果需要子類無法實(shí)例化對象或子類無法被擴(kuò)展,可以將基類的構(gòu)造當(dāng)前138頁,總共346頁。

函數(shù)的訪問屬性設(shè)定為私有2.1子類析構(gòu)函數(shù)隱式調(diào)用基類析構(gòu)函數(shù)

子類的析構(gòu)函數(shù)在執(zhí)行完其中的析構(gòu)代碼,并析構(gòu)完所有的成員變量以后,

會自動調(diào)用其基類的析構(gòu)函數(shù),析構(gòu)該子類對象中的基類子對象(基類析構(gòu)函數(shù)不會調(diào)用子類析構(gòu)函數(shù))

通過基類指針析構(gòu)子類對象,實(shí)際被析構(gòu)的僅僅是子類對象中的基類子對象,

子類的擴(kuò)展部分將失去被析構(gòu)的機(jī)會,極有可能形成內(nèi)存泄漏2.2子類對象的析構(gòu)過程

執(zhí)行析構(gòu)代碼->析構(gòu)成員變量->析構(gòu)基類子對象當(dāng)前139頁,總共346頁。當(dāng)前140頁,總共346頁??截悩?gòu)造函數(shù)拷貝賦值運(yùn)算符函數(shù)繼承中的操作符重載繼承中的拷貝構(gòu)造與拷貝賦值day23當(dāng)前141頁,總共346頁。1拷貝構(gòu)造函數(shù)1.1如果子類未定義拷貝構(gòu)造函數(shù),拷貝過程中的子類將調(diào)用缺省的拷貝構(gòu)造,

其會自動調(diào)用其基類的拷貝構(gòu)造函數(shù),構(gòu)造子類對象中的基類子對象1.2如果子類已定義拷貝構(gòu)造函數(shù),但未顯式指明基類部分的構(gòu)造方式則編譯

器還是選擇基類的缺省構(gòu)造函數(shù)構(gòu)造子類對象中的基類子對象1.3如果子類已定義拷貝構(gòu)造函數(shù),也顯式指明了其基類部分以拷貝方式構(gòu)造

則子類對象中的基類部分和擴(kuò)展部分將一起被復(fù)制當(dāng)前142頁,總共346頁。2拷貝賦值運(yùn)算符函數(shù)2.1如果子類未定義拷貝賦值運(yùn)算符函數(shù),在觸發(fā)拷貝賦值時會調(diào)用子類的缺

省拷貝賦值運(yùn)算符函數(shù),此函數(shù)會自動調(diào)用基類的拷貝賦值運(yùn)算符函數(shù),

復(fù)制子類中的基類子對象2.2如果子類定義了拷貝賦值運(yùn)算符函數(shù),但沒有顯式調(diào)用其基類的拷貝賦值

運(yùn)算符函數(shù),則子類對象中的基類子對象將得不到復(fù)制2.3如果子類定義了拷貝賦值運(yùn)算符函數(shù),且顯示調(diào)用了其基類的拷貝賦值運(yùn)

算符函數(shù),則子類對象中的基類部分和擴(kuò)展部分一起被復(fù)制當(dāng)前143頁,總共346頁。3繼承中的操作符重載

在為子類提供操作符重載定義時,往往需要調(diào)用其基類針對該操作符所做的重

載定義,完成部分工作方法是:通過將子類對象的指針或引用向上造型為其基

類類型的指針或引用,可以迫使針對基類的操作符重載函數(shù)在針對子類的操作

符重載函數(shù)中被調(diào)用4私有子類和保護(hù)子類類型的指針或引用,不能隱式轉(zhuǎn)換為其基類類型的指針或

引用當(dāng)前144頁,總共346頁。當(dāng)前145頁,總共346頁。多重繼承內(nèi)存分配名字沖突多重繼承day24當(dāng)前146頁,總共346頁。1多重繼承:一個類可以同時繼承多個父類的行為和特征功能當(dāng)前147頁,總共346頁。2多重繼承的內(nèi)存分布2.1多重繼承中的子類會有多個基類子對象,他們依據(jù)繼承的順序由低地址到

高地址進(jìn)行排列2.2構(gòu)造函數(shù)也是由繼承的順序依次構(gòu)造子類的基類子對象2.3析構(gòu)函數(shù)則與構(gòu)造的順序相反3名字沖突overloadnamehideBb;A*pa=&b;pa->fun()

在子類的多個基類中,如果在通過子類或在子類中訪問多個基類中同名且并未

隱藏的標(biāo)識符時,發(fā)有名字沖突。

可以通過作用域限定符顯式指明所調(diào)用的基類標(biāo)識符或用using指令來解決當(dāng)前148頁,總共346頁。當(dāng)前149頁,總共346頁。鉆石繼承

鉆石繼承的問題虛繼承鉆石繼承day25虛表,虛表指針當(dāng)前150頁,總共346頁。鉆石繼承:指一個子類繼承自多個基類,且這些基類又繼承自相同的基類當(dāng)前151頁,總共346頁。1鉆石繼承的問題

派生多個中間子類的公共基類子對象,在繼承自多個中間子類的匯聚子類對象

中,存在多個實(shí)例,在匯聚子類中,或通過匯聚子類對象,訪問公共基類的成

員,會因繼承路徑的不同而導(dǎo)致不一致當(dāng)前152頁,總共346頁。2鉆石問題的解決方式

通過虛繼承,可以保證公共基類子對象在匯聚子類對象中,僅存一份實(shí)例,

且為多個中間子類子對象所共享當(dāng)前153頁,總共346頁。3虛繼承虛繼承:

繼承定義中包含了virtual關(guān)鍵字的繼承關(guān)系

虛基類:在虛繼承體系中的通過virtual繼承而來的基類3.1在繼承鏈最末端的子類的構(gòu)造函數(shù)負(fù)責(zé)構(gòu)造虛基類子對象3.2虛基類的所有子類(無論直接的還是間接的)都必須在其構(gòu)造函數(shù)中顯式

指明該虛基類子對象的構(gòu)造方式及拷貝方式構(gòu)造該虛基類子對象,否則

編譯器將選擇以缺省方式構(gòu)造該子對象;3.3與構(gòu)造函數(shù)和拷貝構(gòu)造函數(shù)的情況不同,無論是否存在虛基類,拷貝賦值

運(yùn)算符函數(shù)的實(shí)現(xiàn)沒有區(qū)別

當(dāng)前154頁,總共346頁。4虛表指針

匯聚子類對象中的每個中間子類子對象都持有一個虛表指針,該指針指向一個

被稱為虛表的指針數(shù)組的中部,該數(shù)組的高地址側(cè)存放虛函數(shù)指針,低地址側(cè)

則存放所有虛基類子對象相對于每個中間子類子對象起始地址的偏移量

當(dāng)前155頁,總共346頁。當(dāng)前156頁,總共346頁。多態(tài)虛函數(shù)函數(shù)重寫多態(tài)

day26當(dāng)前157頁,總共346頁。1多態(tài)的一般性描述:

向不同的對象發(fā)送同一消息(函數(shù)調(diào)用),不同的對象在接收時會產(chǎn)生不

同的行為(一個接口,多個方法)foo(){}

(學(xué)校校長向社會發(fā)布9月1日開學(xué),不同對象的響應(yīng))2多態(tài)基于系統(tǒng)實(shí)現(xiàn)角度分為兩類:

靜態(tài)多態(tài)性(之前學(xué)過的函數(shù)重載,運(yùn)算符重載,編譯時決定調(diào)用哪個函

數(shù)),動態(tài)多態(tài)性(運(yùn)行時決定調(diào)用哪個函數(shù))當(dāng)前158頁,總共346頁。3虛函數(shù)

聲明形式:virtual返回類型函數(shù)名(形參表){…}

注:3.1c++規(guī)定,當(dāng)一個成員函數(shù)被聲明為虛函數(shù)后,其派生類中的同名函

數(shù)都自動成為虛函數(shù)(所以在派生類中的函數(shù)可以加virtual也可以

不加)3.2只有類的成員函數(shù)才可以聲明為虛函數(shù)3.3一個成員函數(shù)被聲明為虛函數(shù)后,該類中不允許有其他與其虛函數(shù)相

同簽名的函數(shù)3.3一個類中,除了構(gòu)造函數(shù)和靜態(tài)成員函數(shù)外,任何函數(shù)都可以被聲明

為虛函數(shù)當(dāng)前159頁,總共346頁。4函數(shù)重寫:在父子類中子類提供了一個和父類同名的虛函數(shù)子類的實(shí)現(xiàn)就會

把父類的實(shí)現(xiàn)覆蓋掉(是名字隱藏的一個特例)

5多態(tài):當(dāng)父類型的指針(或者引用)指向子類對象時如果調(diào)用虛函數(shù)并且子類 重寫了這個虛函數(shù)則調(diào)用的表現(xiàn)是子類的否則是父類的

本質(zhì)上去調(diào)用哪個成員函數(shù)完全由調(diào)用者的指針或引用的實(shí)際目標(biāo)對象

的類型決定

5.1繼承是構(gòu)成多態(tài)的基礎(chǔ) 5.2虛函數(shù)是構(gòu)成多態(tài)的關(guān)鍵 5.3函數(shù)重寫是必備條件當(dāng)前160頁,總共346頁。有效的虛函數(shù)數(shù)覆蓋需要滿足如下條件–該函數(shù)必須是成員函數(shù),既不能是全局函數(shù)也不能是靜態(tài)成員凼數(shù)–該函數(shù)必須在基類中用virtual關(guān)鍵字聲明為虛凼數(shù)–覆蓋版本與基類版本必須擁有完全相同的簽名,即函數(shù)名、形參表和常屬性嚴(yán)格一致–如果基類版本返回基本類型數(shù)據(jù),那舉覆蓋版本必須返回相同類型的數(shù)據(jù)–如果基類版本返回類類型對象的指針或引用,那舉覆蓋版本可以返回其子類類型對象的指針或引用當(dāng)前161頁,總共346頁。

如果基類版本帶有異常說明,那舉覆蓋版本不能說明比基類版本拋出更多的異常–無論基類版本位于基類的公有、私有還是保護(hù)部分,覆蓋版本都可以出現(xiàn)在子類包括公有、私有和保護(hù)在內(nèi)的仸何部分全局形式重載的操作符函數(shù)不能形成多態(tài)函數(shù)簽名:函數(shù)名參數(shù)列表常屬性函數(shù)原型:返回值函數(shù)名參數(shù)列表常屬性當(dāng)前162頁,總共346頁。當(dāng)前163頁,總共346頁。純虛函數(shù)與抽象類day27當(dāng)前164頁,總共346頁。1純虛函數(shù)1.1一般聲明形式:virtual返回類型函數(shù)名(形參列表)=0;1.2作用:

純虛函數(shù)無函數(shù)體,聲明純虛函數(shù)是在基類中為其派生類保留一個函數(shù)

名字,為派生類根據(jù)需要對它進(jìn)行定義1.3注意:ABfun()

如果聲明了虛函數(shù),但在派生類中未對其定義,則該虛函數(shù)在派生類中

仍純虛函數(shù)

當(dāng)前165頁,總共346頁。2抽像類

概念:至少擁有一個純虛函數(shù)的類稱為抽象類

特性:2.1無法實(shí)例化對象2.2子類如果不對基類中的全部純虛函數(shù)提供重寫,則該子類也是抽象類

作用:只做為一種基本類型用作繼承的類。也稱為抽象基類3純抽象類:全部由純虛函數(shù)構(gòu)成的抽象類稱為純抽象類(構(gòu)造析構(gòu)除外)引入原因

1、為了方便使用多態(tài)特性,我們常常需要在基類中定義虛擬函數(shù)。

2、在很多情況下,基類本身生成對象是不合情理的當(dāng)前166頁,總共346頁。注意1純虛函數(shù)用來規(guī)范派生類的行為,即接口包含純虛函數(shù)的類是抽象類,抽象

類不能定義實(shí)例2虛函數(shù)必須實(shí)現(xiàn),如果不實(shí)現(xiàn),編譯器將報(bào)錯,錯誤提示為:

errorLNK****:unresolvedexternalsymbol"public:virtualvoid__thiscallClassName::virtualFunctionName(void)“3實(shí)現(xiàn)了純虛函數(shù)的子類,該純虛函數(shù)在子類中就變成了虛函數(shù),子類的子類即

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論