寫(xiě)在前面
C++是一種大型的編程語(yǔ)言,這可能會(huì)嚇倒一些新手?,F(xiàn)代 C++ 可以看成由以下三部分組成:
? 低級(jí)語(yǔ)言,多半繼承自 C。
? 更高級(jí)的語(yǔ)言特征,用戶可以借此定義自己的數(shù)據(jù)類型,組織大規(guī)模的程
序和系統(tǒng)。
? 標(biāo)準(zhǔn)庫(kù),使用上述高級(jí)特征提供一整套有用的數(shù)據(jù)結(jié)構(gòu)和算法。
面向?qū)ο蟮娜蠡咎卣?/h1>
- 封裝:將客觀事物抽象成類,每個(gè)類對(duì)自身的數(shù)據(jù)和方法進(jìn)行操作實(shí)行 protection (private,protected,public)
2.繼承:廣義的繼承有三種實(shí)現(xiàn)形式
1. 實(shí)現(xiàn)繼承:(指使用基類的屬性和方法而無(wú)需額外編碼的能力)
2. 可視繼承:(子窗體使用父窗體的外觀和實(shí)現(xiàn)代碼)
3. 接口繼承:(僅使用屬性和方法,實(shí)現(xiàn)滯后到子類實(shí)現(xiàn))
前兩種(類繼承)和后一種(對(duì)象組合==>接口繼承以及純虛函數(shù))構(gòu)成了功能復(fù)用的兩種方式。
3.多態(tài):子類指針指向父類對(duì)象(iOS篇)。將父類對(duì)象設(shè)置成為和一個(gè)或更多的與他的子類對(duì)象特性以不同的方式運(yùn)作。
1. 隱藏實(shí)現(xiàn)細(xì)節(jié),使得代碼能夠模塊化;擴(kuò)展代碼模塊,實(shí)現(xiàn)代碼重用;
2. 接口重用:為了類在繼承和派生的時(shí)候,保證使用家族中任一類的實(shí)例的某一屬性時(shí)的正確調(diào)用。
C和C++的區(qū)別和聯(lián)系
- 從機(jī)制上說(shuō),C是面向過(guò)程的,C++是面向?qū)ο蟮模⑶姨峁┝祟?/li>
- 從性能上說(shuō),C適合代碼小的,效率高的,如嵌入式;C++更偏向于上層,復(fù)雜的;Linux大部分是C提供的,因?yàn)樗窍到y(tǒng)級(jí)別的,有高效性的需求
- 從名稱上說(shuō),C++比C多+,C++是的超集,并且C++相對(duì)于C來(lái)說(shuō),擴(kuò)展的東西太多
- C++是面向?qū)ο蟮?,更?qiáng)調(diào)是類的設(shè)計(jì)而不是邏輯的設(shè)計(jì)
C++中函數(shù)值的傳遞方式
值傳遞、指針傳遞、引用傳遞
C++中Virtual與inline的含義
在基類成員函數(shù)的聲明前加上virtual關(guān)鍵字,意味著將該成員函數(shù)聲明為虛函數(shù)。inline與函數(shù)的定義體放在一起,使函數(shù)稱為內(nèi)聯(lián)。inline是一種用于實(shí)現(xiàn)的關(guān)鍵字,而不是用于聲明的關(guān)鍵字。
- 虛函數(shù)的特點(diǎn):如果派生類能夠重新定義基類的方法,則在基類中將該方法定義為虛函數(shù)(virtual),這樣可以啟用動(dòng)態(tài)聯(lián)編
- 內(nèi)聯(lián)函數(shù)的特點(diǎn):使用內(nèi)聯(lián)函數(shù)是為了提高函數(shù)的運(yùn)行效率。內(nèi)聯(lián)函數(shù)不能太長(zhǎng),不能包含循環(huán)體,因?yàn)閳?zhí)行循環(huán)體要比調(diào)用函數(shù)開(kāi)銷大(inline)
//MapObj.h
#ifndef __BUILDING__H
#define __BUILDING__H
#include "MapObj.h"
struct SModelBld;
class CBuilding: public CMapObj
{
public :
Building();
virtual BOOL lnit(SlintBase *pObjlnit) ;
virtual BOOL Build(void *p); ————>該派生類CBuilding重新定義基類CMapObj 中的Build方法,則在基類中將該方法定義為虛函數(shù)(virtual),這樣可以啟動(dòng)動(dòng)態(tài)聯(lián)編
protected:
void PutOccupied();
SModeBld m_pModel;
}
#endif
/*
#ifndef HHKDM
#define BJ
#endif
*/
C++開(kāi)發(fā)中常用工具
AppCode :構(gòu)建與JetBrains’ IntelliJ IDEA 平臺(tái)上的用于Objective-C,C,C++,Java和Java開(kāi)發(fā)的集成開(kāi)發(fā)環(huán)境
CLion:來(lái)自JetBrains的跨平臺(tái)的C/C++的集成開(kāi)發(fā)環(huán)境
Code::Blocks :免費(fèi)C,C++和Fortran的集成開(kāi)發(fā)環(huán)境
CodeLite :另一個(gè)跨平臺(tái)的免費(fèi)的C/C++集成開(kāi)發(fā)環(huán)境
Dev-C++:可移植的C/C++/C++11集成開(kāi)發(fā)環(huán)境
Eclipse CDT:基于Eclipse平臺(tái)的功能齊全的C和C++集成開(kāi)發(fā)環(huán)境
Geany :輕量級(jí)的快速,跨平臺(tái)的集成開(kāi)發(fā)環(huán)境。
IBM VisualAge :來(lái)自IBM的家庭計(jì)算機(jī)集成開(kāi)發(fā)環(huán)境。
Irony-mode:由libclang驅(qū)動(dòng)的用于Emacs的C/C++微模式
KDevelop:免費(fèi)開(kāi)源集成開(kāi)發(fā)環(huán)境
Microsoft Visual Studio :來(lái)自微軟的集成開(kāi)發(fā)環(huán)境
NetBeans :主要用于Java開(kāi)發(fā)的的集成開(kāi)發(fā)環(huán)境,也支持其他語(yǔ)言,尤其是PHP,C/C++和HTML5。
Qt Creator:跨平臺(tái)的C++,Javascript和QML集成開(kāi)發(fā)環(huán)境,也是Qt SDK的一部分。
rtags:C/C++的客戶端服務(wù)器索引,用于 跟基于clang的emacs的集成
Xcode :由蘋果公司開(kāi)發(fā)
YouCompleteMe:一個(gè)用于Vim的根據(jù)你敲的代碼快速模糊搜索并進(jìn)行代碼補(bǔ)全的引擎。
構(gòu)建系統(tǒng)
Bear :用于為clang工具生成編譯數(shù)據(jù)庫(kù)的工具
Biicode:基于文件的簡(jiǎn)單依賴管理器。
CMake :跨平臺(tái)的免費(fèi)開(kāi)源軟件用于管理軟件使用獨(dú)立編譯的方法進(jìn)行構(gòu)建的過(guò)程。
CPM:基于CMake和Git的C++包管理器
FASTBuild:高性能,開(kāi)源的構(gòu)建系統(tǒng),支持高度可擴(kuò)展性的編譯,緩沖和網(wǎng)絡(luò)分布。
Ninja :專注于速度的小型構(gòu)建系統(tǒng)
Scons :使用Python scipt 配置的軟件構(gòu)建工具
tundra :高性能的代碼構(gòu)建系統(tǒng),甚至對(duì)于非常大型的軟件項(xiàng)目,也能提供最好的增量構(gòu)建次數(shù)。
tup:基于文件的構(gòu)建系統(tǒng),用于后臺(tái)監(jiān)控變化的文件。
靜態(tài)代碼分析
提高質(zhì)量,減少瑕疵的代碼分析工具列表
Cppcheck :靜態(tài)C/C++代碼分析工具
include-what-you-use :使用clang進(jìn)行代碼分析的工具,可以#include在C和C++文件中。
OCLint :用于C,C++和Objective-C的靜態(tài)源代碼分析工具,用于提高質(zhì)量,減少瑕疵。
Clang Static Analyzer:查找C,C++和Objective-C程序bug的源代碼分析工具
在VC中,編譯工具條內(nèi)Debug與Release選項(xiàng)
- Debug:統(tǒng)稱為調(diào)試版本,包含調(diào)試信息,不做任何優(yōu)化,便于程序員調(diào)試程序。
- Release;稱為發(fā)布版本,往往是進(jìn)行各種優(yōu)化,以便用戶更好的使用
引用和指針
- 引用被創(chuàng)建的同時(shí)必須被初始化(在OC語(yǔ)言中對(duì)象初始化一個(gè)原理,
Person *p = [[Person alloc ]init]在Person對(duì)象創(chuàng)建時(shí),就已經(jīng)初始化和分配內(nèi)存),指針則可以任何時(shí)候被初始化 - 不能有NULL引用,引用必須與合法的存儲(chǔ)單元關(guān)聯(lián)(指針可以是NULL)
- 一旦引用被初始化,就不能改變引用關(guān)系(指針可以隨時(shí)改變所指的對(duì)象)
有了malloc/free但還需要new/delete
- malloc與free是C/C++語(yǔ)言的標(biāo)準(zhǔn)庫(kù)函數(shù),new/delete是C++的運(yùn)算符。
- 她們都用于申請(qǐng)動(dòng)態(tài)內(nèi)存和釋放內(nèi)存,對(duì)于內(nèi)部數(shù)據(jù)的對(duì)象而言,光用malloc和free無(wú)法滿足動(dòng)態(tài)對(duì)象的需求,對(duì)象在創(chuàng)建的同時(shí)要自動(dòng)執(zhí)行構(gòu)造函數(shù),對(duì)象在消失之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)。
- 由于malloc/free是庫(kù)函數(shù)不是元素符,不在編譯器控制權(quán)限內(nèi),不能把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。因此C++語(yǔ)言需要一個(gè)能完成動(dòng)態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new,以及能夠完成清理與釋放內(nèi)存工作的運(yùn)算符delete
?new/delete不是庫(kù)函數(shù),是運(yùn)算符
用C++寫(xiě)一個(gè)程序,如何判斷一個(gè)操作系統(tǒng)是16位還是32位
- 定義指針
p,打印出sizeof(p),結(jié)果是4,則是32位操作系統(tǒng),結(jié)果是2,則是6位操作系統(tǒng)
int a=0;
if(a>65536)
{
count<<"32 bit"<<endl;
}
else
{
count<<"16 bit"<<endl;
}
函數(shù)指針
- void((fp1)(int))[10]:fp1是個(gè)指針,指向一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)為int型,函數(shù)返回值是一個(gè)指針,這個(gè)指針指向一個(gè)數(shù)組,這個(gè)數(shù)組10個(gè)元素,每個(gè)元素是一個(gè)void型指針
- float((fp2)(int,int,int))(int):fp2是個(gè)指針,指向一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)為3個(gè)int型,函數(shù)的返回值是一個(gè)指針,這個(gè)指針指向一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)為int型,函數(shù)的返回值是float型
「float(*p)(int) p=[(*fp2)(int,int,int)]」 - int((fp3)())10:fp3是一個(gè)指針,指向一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)為空,函數(shù)的返回值是一個(gè)指針,這個(gè)指針指向一個(gè)數(shù)組,這個(gè)數(shù)組有10個(gè)元素,每個(gè)元素是一個(gè)指針,指向一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)為空,函數(shù)返回值是int型
內(nèi)存分配的方式
1.靜態(tài)存儲(chǔ)區(qū)域分配:內(nèi)存在編譯的時(shí)候已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量
- 在棧上創(chuàng)建:執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束這些存儲(chǔ)單元自動(dòng)被釋放,棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限
3.從堆上分配:亦稱動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc/new申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free/delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期有我們決定。使用靈活但是問(wèn)題最多。
全局變量和局部變量
- 聲明周期:全局變量隨主程序創(chuàng)建而創(chuàng)建,隨主程序的銷毀而銷毀;局部變量在局部函數(shù)內(nèi)部,甚至局部循環(huán)體等內(nèi)部存在,推出布局函數(shù)或則循環(huán)體局部變量久不存在了;內(nèi)存中分配在全局?jǐn)?shù)據(jù)區(qū)。
- 使用方式:通過(guò)聲明后全局變量程序的各個(gè)部分都可以用到;局部變量只能在局部使用;分配在棧區(qū)。
- 操作系統(tǒng)和編譯器通過(guò)內(nèi)存分配的位置知道的,全局變量分配在全局?jǐn)?shù)據(jù)段并且在程序開(kāi)始運(yùn)行的時(shí)候被加載。局部變量則分配在堆棧里 面。
堆棧、靜態(tài)區(qū)動(dòng)態(tài)區(qū)、靜態(tài)庫(kù)動(dòng)態(tài)庫(kù)
棧(stack):是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存區(qū)域。意義是棧頂?shù)牡刂泛拖到y(tǒng)最大容量預(yù)先有系統(tǒng)設(shè)定。由于棧是先進(jìn)后出的隊(duì)列(安全),所以不存在內(nèi)存泄漏。
堆(heap):是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的一塊內(nèi)存區(qū)域。系統(tǒng)是用鏈表存儲(chǔ)的空閑內(nèi)存地址,堆的大小受限于系統(tǒng)有效的虛擬內(nèi)存。
碎片問(wèn)題:堆會(huì)頻繁的new/delete 自然會(huì)產(chǎn)生碎片,而棧是先進(jìn)后出 一一對(duì)應(yīng),不存在碎片問(wèn)題。
分配方式:堆都是動(dòng)態(tài)分配的。棧有靜態(tài)和動(dòng)態(tài)分配。靜態(tài)分配是編譯器分配的 比如:局部變量的分配,動(dòng)態(tài)分配是由alloc函數(shù)分配。但是棧的動(dòng)態(tài)分配是由編譯器釋放,不用人手動(dòng)釋放。
內(nèi)存分區(qū)情況(iOS篇):
靜態(tài)庫(kù):.a .framework 在項(xiàng)目中使用靜態(tài)庫(kù),在進(jìn)行編譯靜態(tài)庫(kù)會(huì)和代碼鏈接生成目標(biāo)文件,這樣會(huì)導(dǎo)致編譯后的目標(biāo)文件過(guò)大,但因?yàn)殒溄拥揭黄鹆耸褂渺o態(tài)庫(kù)函數(shù)時(shí) 不用再加載其他函數(shù)庫(kù)。
動(dòng)態(tài)庫(kù):.dylib .framework 在編譯時(shí)不會(huì)和代碼鏈接到一塊,這樣編譯后的目標(biāo)文件比較小,但使用動(dòng)態(tài)庫(kù)函數(shù)時(shí)需提前加載函數(shù)庫(kù)(項(xiàng)目工程-Build Phases-Copy Buildle Resoce 手動(dòng)添加)自己手動(dòng)建立動(dòng)靜態(tài)庫(kù)
Heap(堆) stack(棧):
stack的空間由操作系統(tǒng)自動(dòng)分配/釋放,heap程序員手動(dòng)分配和釋放。
stack空間有限,heap是很大的自由存儲(chǔ)區(qū)
C中的malloc函數(shù)分配的內(nèi)存空間即在堆上,C++對(duì)應(yīng)的是new操作符
程序在編譯期對(duì)變量和函數(shù)分配內(nèi)存在棧上進(jìn)行,且程序運(yùn)行過(guò)程中函數(shù)調(diào)用時(shí)參數(shù)的傳遞也在棧上進(jìn)行
static靜態(tài)變量(iOS篇):需要一個(gè)數(shù)據(jù)為整類而非某個(gè)對(duì)象使用,同時(shí)具有封裝性。要求此成員隱藏在內(nèi)部,對(duì)外不可見(jiàn)。
優(yōu)點(diǎn):節(jié)省內(nèi)存。只存儲(chǔ)一次,供所有對(duì)象使用
值可更新。
提高效率。某個(gè)對(duì)象對(duì)值修改一次,所有對(duì)象都能使用新的值。
單例
//單例(iOS)
+(instancetype)sharedManager {
static PlayManager *handle = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
handle = [[PlayManager alloc]init];
});
return handle;
}
//UITableView 加載cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
這里定義的static變量在編譯時(shí)決定其類型,只有在方法cellForRowAtIndexPath下才可以訪問(wèn)。
extern全局變量:也稱為外部變量,是在方法外部定義的變量。它不屬于哪個(gè)方法,而屬于整個(gè)源程序。
局部變量:方法內(nèi)定義說(shuō)明,作用域僅限于方法內(nèi)。
** 實(shí)例變量**:在類中定義的實(shí)例變量,可以在各個(gè)方法中使用。
const:變量值不可變。const int a;a是個(gè)長(zhǎng)整數(shù)
volatile:變量隨時(shí)改變
**static關(guān)鍵字區(qū)別:**
static全局變量和普通全局變量有什么區(qū)別:static全局變量只初始化一次,防止在其他文件單元中被引用。
static局部變量和普通局部變量有什么區(qū)別:static變量只初始化一次,下次使用上次結(jié)果值。
static函數(shù)和普通函數(shù)有什么區(qū)別:static函數(shù)只有一份內(nèi)存,普通函數(shù)在每次調(diào)用時(shí)都會(huì)被copy一次。
C++中析構(gòu)函數(shù)和虛函數(shù)用法
析構(gòu)函數(shù):是特殊的類成員函數(shù),它沒(méi)有返回值,沒(méi)有參數(shù),不能隨意調(diào)用,也沒(méi)有重載,只有在類對(duì)象的聲明周期結(jié)束的時(shí)候,由系統(tǒng)自動(dòng)調(diào)用。有釋放內(nèi)存空間的作用。
虛函數(shù):是C++多態(tài)的一種表現(xiàn),使用虛函數(shù),我們可以靈活的進(jìn)行動(dòng)態(tài)綁定,當(dāng)然是以一定的開(kāi)銷為代價(jià)。

C++虛函數(shù)與多態(tài)的關(guān)系
在面向?qū)ο笾械某绦蛟O(shè)計(jì)中,經(jīng)常會(huì)用到類的繼承,且保留基類的特性,以減少開(kāi)發(fā)時(shí)間
C++內(nèi)聯(lián)函數(shù)