c++筆記

cpp技術(shù)知識點筆記:

1:list 和 vector的實現(xiàn)區(qū)別?

list空間按需分配,是鏈表類型,內(nèi)存不一定連續(xù),在插入和刪除的時候不會引起迭代器失效,刪除元素只有當(dāng)前元素的迭代器失效

vector的空間是連續(xù)的,空間不足的情況下,(1)開辟新的大內(nèi)存空間;(2)從舊的空間拷貝數(shù)據(jù)到新的內(nèi)存空間;(3)釋放舊的空間

vector的內(nèi)部空間,總是供大于需,避免頻繁的數(shù)據(jù)移動操作,size = 2*size 插入和刪除可能引起迭代器失效。

vector的刪除操作引起迭代器失效:刪除可能導(dǎo)致某個迭代器訪問不再合法、然后繼續(xù)訪問就有可能訪問已經(jīng)失效的空間。

2:指針和引用?

指針有空間,存儲的是一個地址。引用只是變量別名。

指針可以為NULL,引用不可以為空。

指針可以在初始化之后,改變指向,引用一旦初始化將不能改變。

存在const修飾的指針,不可以改變指向,不存在const修飾的引用。

指針可以有二級操作,**p 引用沒有。

指針指向的變量,需要解引用,引用直接訪問就行。

指針和引用自增的含義不同。

3:define和const區(qū)別?

define定義的是一個字符串,沒有類型,沒有存儲器,編譯器不對其進行安全檢查,const有類型,存在數(shù)據(jù)段,可以進行安全檢查。

define不可以調(diào)試,const可以調(diào)試。

define在預(yù)處理時進行替換,const在編譯時進行。

4:char arr[10]; 和 char *p = new char[10] 區(qū)別?

char arr[10]; 字符數(shù)組未初始化 ,存放在未初始化的的數(shù)據(jù)區(qū),如果存在static修飾,則存放在靜態(tài)數(shù)據(jù)區(qū)。

new char[10]; 定義的字符數(shù)組,使用'/0'進行初始化,存放在堆中。

5:c++的內(nèi)存分配方式?內(nèi)存分布圖?

new、malloc分配空間,需要手動釋放。

系統(tǒng)在棧上分配空間,函數(shù)調(diào)用的參數(shù)信息,系統(tǒng)釋放。

static靜態(tài)存儲分配空間。

? ? ? ? 棧

? ? ? ? 堆

? ? 未初始化數(shù)據(jù)段

? ? 初始化數(shù)據(jù)段

? ? ? 代碼段

6:自實現(xiàn)String類:?

class String

{

? ? public:

? ? ? ? String(const char *str);

? ? ? ? String(const String &other);

? ? ? ? String& operator=(const String &other);

? ? ? ? ~String();

? ? private:

? ? ? ? m_data;

? ? ? ? m_size;

}

String::String(const char* str)

{

? ? if(str == nullptr)

? ? {

? ? ? ? m_data = new char[1];

? ? ? ? m_data[0] = '\0';

? ? ? ? m_size = 0;

? ? }

? ? else

? ? {

? ? ? ? m_size = strlen(str);

? ? ? ? m_data = new char[m_size + 1];

? ? ? ? strcpy(m_data, str);

? ? }

}

String::String(const String& other)

{

? ? m_size = other.m_size;

? ? m_data = new char[m_size + 1];

? ? strcpy(m_data, other.m_data);

}

String::String& operator=(const String& other)

{

? ? if(this == &other)

? ? {

? ? ? ? return *this;

? ? }

? ? delete[] m_data;

? ? m_size = strlen(other.m_data);

? ? m_data = new char[m_size + 1];

? ? strcpy(m_data, other.m_data);

? ? return *this;

}

7:extern關(guān)鍵字?

置于變量或者函數(shù)前,表示變量或者函數(shù)定義在別的文件中。

extern 和 C連用的時候,告訴編譯器編譯時候用c的方式編譯。

當(dāng)不與c連用的時候,作用聲明函數(shù)或者全局變量的作用范圍。

8:static關(guān)鍵字?

? 1.修飾局部變量:存放在靜態(tài)變量區(qū),聲明周期和main函數(shù)相同,main函數(shù)之前初始化,函數(shù)結(jié)束退出。

? 2.修飾全局變量:全局變量原本就存放在靜態(tài)區(qū),static修飾,使其只能被包含該定義的文件訪問,修改了其作用域。

? 3.修飾函數(shù):static修飾的函數(shù),只能在包含改定義的文件中調(diào)用,靜態(tài)函數(shù),聲明和定義需要在同一個文件中。

? 4.修飾成員變量:使其成為類的全局變量,所有類對象共享,包括派生類,只能在類外進行初始化。可以使用const修飾在類內(nèi)進行初始化。

? ? 靜態(tài)數(shù)據(jù)成員,實體遠(yuǎn)在main函數(shù)開始前已經(jīng)在全局?jǐn)?shù)據(jù)段中誕生了。生命周期和類對象是異步的。這個時候類對象還沒有開始,但是靜態(tài)數(shù)據(jù)成員已經(jīng)可以訪問了。為了此所以一定要在類外初始化。

? 5.成員函數(shù):只存在一份該函數(shù),所有對象共享,不含this指針,無需創(chuàng)建任何對象就可以訪問。

? 不可以同時使用const和static修飾成員函數(shù),原因c++在實現(xiàn)const修飾的函數(shù)時候,會在函數(shù)中隱式添加一個const this*,static是沒有this指針的,互相矛盾。

9:volatile作用?

修飾變量,表名某個變量隨時可能會被外部改變,改變量不能被緩存到寄存器,每次需要重新讀取。

10:const的作用?

? 1.修飾變量,只讀變量,不可以被更改。

? 2.修飾函數(shù)參數(shù)(返回值,一般很少用),參數(shù)內(nèi)容不能被修改

? 3.修飾指針,指針?biāo)笇ο蟛荒鼙桓淖?。int* const p = &a; 指針p指向a的地址,不能再被改變。

? 4.修飾指針?biāo)傅淖兞?,int const *p = &a; const修飾*p, *p所指的內(nèi)容不能被改變。

? 5.修飾類成員函數(shù),表明是一個常函數(shù),不能修改類的成員變量。

? 一個成員函數(shù)不會修改成員值,最好將其修飾為const函數(shù),void func() const;

11: new和malloc?

malloc和free是C語言的標(biāo)準(zhǔn)庫函數(shù),new和delete是c++的運算符,都可以進行申請內(nèi)存和釋放內(nèi)存。

對于非內(nèi)部數(shù)據(jù)結(jié)構(gòu)的類型而言,malloc和free無法滿足動態(tài)對象要求。

new可以認(rèn)為是malloc加構(gòu)造函數(shù)的執(zhí)行,new出來的指針是直接帶構(gòu)造信息的,malloc返回的都是void指針。

12:c++多態(tài)?

一個接口,多種方法,c++多態(tài)主要通過虛函數(shù)實現(xiàn)的,虛函數(shù)允許子類從寫overrid。

編譯時多態(tài):通過重載函數(shù)實現(xiàn)。

運行時多態(tài):通過虛函數(shù)實現(xiàn)。

13: c++的虛函數(shù) 純虛函數(shù)?

純虛函數(shù)是在基類中聲明的虛函數(shù),基類中沒有定義,函數(shù)原型后加=0,純虛函數(shù)的實現(xiàn)起到規(guī)范作用,繼承的類必須按照這個形式自己實現(xiàn)。

虛函數(shù),運行時多態(tài),父類提供虛函數(shù)實現(xiàn),子類可以重寫父類虛函數(shù)實現(xiàn)子類的特殊化。

c++包含純虛函數(shù)的類是抽象類,抽象類不能new出對象。只有實現(xiàn)了純虛函數(shù)的子類,才可以。

14: 靜態(tài)綁定和動態(tài)綁定?

靜態(tài)綁定發(fā)生在編譯期,動態(tài)綁定發(fā)生在運行期。

動態(tài)類型可以更改,靜態(tài)類型不可以更改。

繼承體系中,只有虛函數(shù)使用的是動態(tài)綁定,其它使用的都是靜態(tài)綁定。

靜態(tài)多態(tài)使用的是模板技術(shù),或者是函數(shù)重載技術(shù)。動態(tài)多態(tài)通過虛函數(shù)實現(xiàn)在運行期綁定的技術(shù)。

15:值傳遞和引用傳遞?

值傳遞是指當(dāng)函數(shù)發(fā)生函數(shù)調(diào)用時候,給形參分配空間,用實參來初始化形參,這一過程是參數(shù)值得單項傳遞。形參不影響實參。

引用傳遞,將引用作為形參,系統(tǒng)初始化時,自動使用實參來初始化形參,形參是實參的一個別名,直接操作的是實參。

16: 內(nèi)聯(lián)函數(shù)?特點?

將inline放在函數(shù)聲明前不起任何作用,必須要放在定義函數(shù)前。

使用關(guān)鍵字inline的函數(shù),編譯器在調(diào)用處,使用函數(shù)體進行替換,節(jié)省參數(shù)傳遞,控制轉(zhuǎn)移開銷。

內(nèi)聯(lián)函數(shù)不能有循環(huán),和switch語句;

內(nèi)聯(lián)函數(shù)定義,必須出現(xiàn)在第一次調(diào)用之前;不能有異常聲明。

17: 拷貝構(gòu)造函數(shù)和 operator=?

前者屬于構(gòu)造函數(shù),后者屬于運算符重載。

對于在賦值操作之前,還沒有構(gòu)造的變量,調(diào)用拷貝構(gòu)造函數(shù)。

賦值之前,已經(jīng)構(gòu)造的變量,調(diào)用賦值操作。

class_obj a("xxx"); class_obj b = a; //拷貝構(gòu)造 class_obj c; c = a; // 賦值operator=

18: 友元函數(shù)?

friend修飾,不可以繼承,不可以傳遞,可以訪問相應(yīng)類的公有,私有,受保護的成員。

19: 抽象類?

帶有純虛函數(shù)的類叫抽象類。

純虛函數(shù):基類中僅僅給出聲明,不對虛函數(shù)實現(xiàn)定義,而是在派生類中實現(xiàn),該函數(shù)成為純虛函數(shù)。

抽象類的析構(gòu)函數(shù)應(yīng)被聲明為virtaul,因為涉及到繼承。

20: 虛構(gòu)造函數(shù)?虛析構(gòu)函數(shù)?

不能聲明虛構(gòu)造函數(shù),多態(tài)是不同對象對同一消息的不同特性,虛函數(shù)作為運行多態(tài)的基礎(chǔ),主要針對對象,構(gòu)造函數(shù)是在對象生成之前運行的,沒有意義。

可以聲明為虛析構(gòu)函數(shù),析構(gòu)函數(shù)是對象釋放的一些清理工作,一個類的析構(gòu)函數(shù)是虛函數(shù),由它派生而來的所有子類也是虛函數(shù),析構(gòu)函數(shù)設(shè)置為虛函數(shù),就可以

調(diào)用適當(dāng)?shù)奈鰳?gòu)函數(shù)對不同的對象進行清理工作。

21: 函數(shù)重載和函數(shù)重寫?

重載:同名不同參的函數(shù),互相被稱為重載函數(shù)。

? ? 條件:1.名必須相同,2.參數(shù)必須不同,3.返回值都可。

重寫:也可叫覆蓋,繼承中,子類重新定義父類中有相同名稱和參數(shù)的虛函數(shù)。

? ? 條件:1.兩個函數(shù)都必須是虛函數(shù),一個在基類,一個在派生類。2.函數(shù)名和參數(shù)必須一致。3.返回值相同。

22: class和struct?

默認(rèn)成員訪問權(quán)限不同,struct是公有訪問,class是私有訪問。

默認(rèn)繼承方式不同,struct是公有繼承, class是私有繼承。

定義模板時可以使用class,不能使用struct。

都可以包含成員函數(shù),實現(xiàn)繼承,都可以實現(xiàn)多態(tài)。

23: 淺拷貝和深拷貝?

對一個對象進行拷貝,默認(rèn)是復(fù)制構(gòu)造拷貝,兩個對象的指針成員所指內(nèi)存相同。只對指針進行拷貝。

編譯器在我們沒有定義拷貝構(gòu)造函數(shù)時候,采用默認(rèn)拷貝構(gòu)造函數(shù),進行淺拷貝,兩個指針指向同一個內(nèi)存空間。

深拷貝不但對指針進行拷貝,而且對指針?biāo)竷?nèi)容也進行了拷貝,深拷貝的內(nèi)容兩份,淺拷貝內(nèi)容一份。

24: 析構(gòu)函數(shù)帶virtual?

基類派生,析構(gòu)函數(shù)一定要帶virtaul關(guān)鍵字,基類指針指向派生類對象,刪除該指針時,并不會釋放派生類對象的空間,不會調(diào)用派生類析構(gòu)函數(shù)。

不需要基類指針指向派生類對象,可以不用帶virtaul。

25: delete 和 delete[]?

delete釋放內(nèi)存,delete ptr釋放ptr指向的內(nèi)存。

delete[] 釋放內(nèi)存,逐一調(diào)用數(shù)組的每個對象的析構(gòu)函數(shù),全部釋放。

26: 顯示轉(zhuǎn)換?

static_cast: 基本類型之間的數(shù)據(jù)轉(zhuǎn)換。

const_cast: 將const類型的指針轉(zhuǎn)換為非const類型的指針。

reinterpret_cast: 不相關(guān)類型之間的轉(zhuǎn)化,目標(biāo)和原始之間有相同的位數(shù)。

dynamic_cast: 運行時檢查轉(zhuǎn)換是否安全,用于類層次間的上行和下行轉(zhuǎn)化。

27: 運算符重載?

實際上是函數(shù)重載,改變運算符的操作方式,使其可以適用類類型,為類提供一個接口,使語言面向問題而不是面向程序。

增強c++的擴展性。

28: stl?

c++提供的標(biāo)準(zhǔn)模板庫。

組成:容器,迭代器,算法,函數(shù)對象適配器。算法位于核心。

29: auto?

const 和 volatile c++的兩種屬性

聲明為auto的變量不能從初始表達(dá)式中帶走cv(上面那兩種)限制符

const int a = 1; auto b = a; // b int類型? auto &c = a; // c是const int類型

decltype則可以帶走cv限制符。

但是,如果是一個對象的定義中含有const或volatile限制符,使用decltype進行推導(dǎo)時候,其成員不會繼承cv的限制。

30: 預(yù)處理->編譯->匯編->鏈接?

1 預(yù)編譯 過程主要處理那些源文件中的以“#”開始的預(yù)編譯指令,主要處理規(guī)則有:

? ? 1.將所有的“#define”刪除,并展開所用的宏定義

? ? 2.處理所有條件預(yù)編譯指令,比如“#if”、“#ifdef”、 “#elif”、“#endif”

? ? 3.處理“#include”預(yù)編譯指令,將被包含的文件插入到該編譯指令的位置,注:此過程是遞歸進行的

? ? 4.刪除所有注釋

? ? 5.添加行號和文件名標(biāo)識,以便于編譯時編譯器產(chǎn)生調(diào)試用的行號信息以及用于編譯時產(chǎn)生編譯錯誤或警告時可顯示行號

? ? 6.保留所有的#pragma編譯器指令。

2 編譯 過程就是把預(yù)處理完的文件進行一系列的詞法分析、語法分析、語義分析及優(yōu)化后生成相應(yīng)的匯編代碼文件。這個過程是整個程序構(gòu)建的核心部分

3 匯編 器是將匯編代碼轉(zhuǎn)化成機器可以執(zhí)行的指令,每一條匯編語句幾乎都是一條機器指令。經(jīng)過編譯、鏈接、匯編輸出的文件成為目標(biāo)文件。

4 鏈接 的主要內(nèi)容就是把各個模塊之間相互引用的部分處理好,使各個模塊可以正確的拼接。 鏈接的主要過程包塊 地址和空間的分配、符號決議和重定位等步驟。

31: 靜態(tài)鏈接和動態(tài)鏈接?

靜態(tài):靜態(tài)鏈接的時候,載入代碼就會把程序會用到的動態(tài)代碼或動態(tài)代碼的地址確定下來。

動態(tài):直到真正調(diào)用動態(tài)庫代碼時,載入程序才計算(被調(diào)用的那部分)動態(tài)代碼的邏輯地址,但運行期間的性能比不上靜態(tài)鏈接的程序。

32: 構(gòu)造函數(shù)存在自動轉(zhuǎn)換功能:

聲明構(gòu)造函數(shù)的時候前面添加上explicit即可,這樣就可以防止這種自動的轉(zhuǎn)換操作。

33: 關(guān)鍵字registr,typdef的作用?

regist盡可能讓變量保存在cpu的寄存器中,減去cpu從內(nèi)存抓取效率,提高運行效率。

注意:

? ? 局部變量才可以被修飾register

? ? 不能取地址,地址存放在內(nèi)存,但是它在寄存器。

? ? 一定是cpu所接受的類型。

typedef:起一個新名字。

? ? 提高移植性。

? ? 提高編碼效率。

? ? 解釋數(shù)據(jù)類型作用。

34:explicit關(guān)鍵字的作用?

編譯器有記憶功能,為的是將頻繁使用到的變量,保存在寄存器中,提高效率。

但是如果該變量在內(nèi)存中被改動了,寄存器中的值就不再有效,但是計算器不知道,還是會使用寄存器中的值。

解決此辦法就是加上關(guān)鍵字explicit關(guān)鍵字,提醒cpu每次從內(nèi)存中取改值。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,675評論 1 51
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,656評論 1 32
  • C++ 是 C 語言的超集,它是一種使用非常廣泛的計算機編程語言。C++ 作為一種靜態(tài)數(shù)據(jù)類型檢查的、支持多范型的...
    神齊閱讀 1,099評論 0 1
  • 題目類型 a.C++與C差異(1-18) 1.C和C++中struct有什么區(qū)別? C沒有Protection行為...
    阿面a閱讀 7,891評論 0 10
  • (一)讀紅樓夢的歷程 第一次讀《紅樓夢》的時候在初三,當(dāng)時讀書的初衷是只是因為人人都說《紅樓夢》好,我要看看到底好...
    阡陌千尋閱讀 776評論 0 5

友情鏈接更多精彩內(nèi)容