小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

一網(wǎng)打盡!完整整理的C++面試題集錦

 深度Linux 2024-04-10 發(fā)布于湖南

歡迎來(lái)到C++面試環(huán)節(jié)!在這個(gè)階段,我們將測(cè)試您對(duì)C++語(yǔ)言的理解和應(yīng)用能力。通過(guò)這些問(wèn)題,我們希望了解您對(duì)C++基礎(chǔ)知識(shí)、面向?qū)ο缶幊?、模板、STL等方面的掌握情況。請(qǐng)放松心態(tài),盡力回答每個(gè)問(wèn)題,并且在可能的情況下提供示例代碼或具體解釋。準(zhǔn)備好了嗎?讓我們開(kāi)始吧!

1、談?wù)勀銓?duì)面向過(guò)程和面向?qū)ο蟮膮^(qū)別

面向過(guò)程編程(Procedure-oriented programming)和面向?qū)ο缶幊蹋∣bject-oriented programming)是兩種不同的編程范式。

面向過(guò)程編程是以解決問(wèn)題的步驟為中心,通過(guò)定義一系列的函數(shù)或過(guò)程來(lái)實(shí)現(xiàn)程序邏輯。程序被分解為一組函數(shù),每個(gè)函數(shù)負(fù)責(zé)特定的任務(wù),數(shù)據(jù)與函數(shù)分離。面向過(guò)程更注重算法和流程控制,將問(wèn)題劃分為一系列的步驟來(lái)處理。

面向?qū)ο缶幊虅t以對(duì)象為核心,將數(shù)據(jù)和操作封裝在一個(gè)對(duì)象內(nèi)部。對(duì)象包含屬性(數(shù)據(jù))和方法(操作),通過(guò)定義類來(lái)創(chuàng)建具體的對(duì)象實(shí)例。面向?qū)ο蟾⒅爻橄蟆⒎庋b、繼承和多態(tài)等概念,通過(guò)建立對(duì)象之間的關(guān)系來(lái)完成程序設(shè)計(jì)。

區(qū)別如下:

抽象層次不同:面向過(guò)程更關(guān)注步驟和算法,而面向?qū)ο蟾P(guān)注對(duì)象和其行為。

數(shù)據(jù)封裝性不同:面向過(guò)程中數(shù)據(jù)與函數(shù)分離,而面向?qū)ο笾袛?shù)據(jù)與方法封裝在一個(gè)對(duì)象內(nèi)部。

繼承和多態(tài)支持不同:面向過(guò)程無(wú)繼承和多態(tài)概念,而這是面向?qū)ο缶幊痰暮诵奶匦灾弧?/p>

代碼復(fù)用方式不同:面向過(guò)程通過(guò)模塊化設(shè)計(jì)實(shí)現(xiàn)代碼復(fù)用,而面向?qū)ο笸ㄟ^(guò)類和對(duì)象的繼承和組合來(lái)實(shí)現(xiàn)代碼復(fù)用。

選擇面向過(guò)程還是面向?qū)ο缶幊?,取決于具體的項(xiàng)目需求、開(kāi)發(fā)團(tuán)隊(duì)和個(gè)人偏好。在大型項(xiàng)目中,面向?qū)ο蟾S?,因?yàn)樗芴峁└玫目删S護(hù)性、可擴(kuò)展性和代碼復(fù)用性。而對(duì)于小規(guī)?;蚝?jiǎn)單的問(wèn)題,面向過(guò)程可能更加直觀且高效。

2、C和C++的區(qū)別

面向?qū)ο笾С郑篊++是一種面向?qū)ο蟮木幊陶Z(yǔ)言,支持類、繼承、多態(tài)等面向?qū)ο蟮奶匦?。而C語(yǔ)言則是一種面向過(guò)程的編程語(yǔ)言,沒(méi)有直接支持面向?qū)ο蟮奶匦浴?/p>

擴(kuò)展性和封裝性:由于支持面向?qū)ο缶幊谭妒?,C++提供了更豐富的特性和功能,可以實(shí)現(xiàn)數(shù)據(jù)與方法的封裝,并支持繼承和多態(tài)等機(jī)制。這使得代碼可重用性更強(qiáng)、模塊化更好,并能夠構(gòu)建大型復(fù)雜軟件系統(tǒng)。相比之下,C語(yǔ)言相對(duì)簡(jiǎn)單,更適合于較小規(guī)模的項(xiàng)目或者需要對(duì)硬件進(jìn)行底層操作的場(chǎng)景。

標(biāo)準(zhǔn)庫(kù)差異:C標(biāo)準(zhǔn)庫(kù)主要提供了基本輸入輸出、字符串處理等功能函數(shù)。而C++標(biāo)準(zhǔn)庫(kù)除了包含了所有C標(biāo)準(zhǔn)庫(kù)函數(shù)外,還添加了對(duì)面向?qū)ο筇匦裕ㄈ缛萜鳌⑺惴ǎ┑闹С帧?/p>

異常處理機(jī)制:C++引入了異常處理機(jī)制,在程序出現(xiàn)錯(cuò)誤時(shí)可以拋出異常并在適當(dāng)位置進(jìn)行捕獲和處理。而C語(yǔ)言沒(méi)有內(nèi)置的異常處理機(jī)制,錯(cuò)誤通常通過(guò)返回特定值或使用全局變量來(lái)處理。

編譯器支持:C++編譯器一般也可以編譯C代碼,因?yàn)镃++是在C的基礎(chǔ)上發(fā)展起來(lái)的。但是C編譯器不一定能夠完全支持C++語(yǔ)法和特性。

3、static關(guān)鍵字的作用

靜態(tài)變量:在函數(shù)內(nèi)部使用static修飾的局部變量稱為靜態(tài)變量。靜態(tài)變量的生命周期與程序運(yùn)行期間保持一致,而不是隨著函數(shù)調(diào)用的結(jié)束而銷毀。每次調(diào)用函數(shù)時(shí),靜態(tài)變量的值會(huì)保留上一次函數(shù)調(diào)用后的值。void increment() {

static int counter = 0;

counter++;

cout << "Counter: " << counter << endl;

}

int main() {

increment(); // 輸出 Counter: 1

increment(); // 輸出 Counter: 2

increment(); // 輸出 Counter: 3

return 0;

}

靜態(tài)函數(shù):在函數(shù)聲明或定義前面使用static關(guān)鍵字修飾,表示該函數(shù)僅在當(dāng)前文件范圍內(nèi)可見(jiàn),不能被其他文件訪問(wèn)。靜態(tài)函數(shù)對(duì)于限制函數(shù)作用域和避免命名沖突很有用。// 在同一個(gè)文件中定義的靜態(tài)函數(shù)

static void internalFunction() {

cout << "This is an internal function." << endl;

}

int main() {

internalFunction(); // 調(diào)用靜態(tài)函數(shù),輸出 This is an internal function.

return 0;

}

靜態(tài)全局變量:在全局作用域下使用static修飾的變量稱為靜態(tài)全局變量。靜態(tài)全局變量只能在聲明它的源文件中訪問(wèn),無(wú)法被其他文件引用。這樣可以防止不同源文件之間的命名沖突。

靜態(tài)類成員:在類中使用static關(guān)鍵字修飾成員變量或成員函數(shù),表示它們屬于類本身而不是實(shí)例對(duì)象。靜態(tài)成員可以通過(guò)類名直接訪問(wèn),無(wú)需創(chuàng)建對(duì)象實(shí)例。靜態(tài)成員共享于所有類的實(shí)例,并且具有全局作用域。class MyClass {

public:

static int count;

static void increaseCount() {

count++;

cout << "Count: " << count << endl;

}

};

int MyClass::count = 0; // 初始化靜態(tài)成員

int main() {

MyClass::increaseCount(); // 輸出 Count: 1

MyClass::increaseCount(); // 輸出 Count: 2

return 0;

}

4、const關(guān)鍵字的作用

const關(guān)鍵字用于聲明一個(gè)常量,它可以應(yīng)用于變量、函數(shù)參數(shù)和函數(shù)返回類型。它的作用有以下幾個(gè)方面:

聲明常量變量:使用const關(guān)鍵字可以將一個(gè)變量聲明為只讀,即不可修改的常量。const int MAX_VALUE = 100;

保護(hù)函數(shù)參數(shù):在函數(shù)定義中,使用const關(guān)鍵字可以指定某些參數(shù)為只讀,防止其被修改。void printMessage(const string& message) {

cout << message << endl;

}

防止函數(shù)修改對(duì)象狀態(tài):在成員函數(shù)后面加上const關(guān)鍵字表示該成員函數(shù)不會(huì)修改對(duì)象的狀態(tài)。class MyClass {

public:

void printValue() const {

cout << value << endl;

}

private:

int value;

};

限制返回值的修改:在函數(shù)定義或聲明中使用const關(guān)鍵字來(lái)指定返回值為只讀,禁止對(duì)返回值進(jìn)行修改。const int getValue() {

return 42;

}

5、synchronized 關(guān)鍵字和volatile關(guān)鍵字區(qū)別

synchronized關(guān)鍵字:

C++沒(méi)有直接對(duì)應(yīng)Java中synchronized關(guān)鍵字的語(yǔ)法。相對(duì)于Java中基于內(nèi)置鎖的同步機(jī)制,C++提供了更多靈活的同步選項(xiàng)。

可以使用互斥量(mutex)來(lái)實(shí)現(xiàn)類似synchronized的功能。互斥量可以通過(guò)加鎖和解鎖操作保證臨界區(qū)代碼的互斥訪問(wèn)。

volatile關(guān)鍵字:

在C++中,volatile關(guān)鍵字用于指示編譯器不對(duì)變量進(jìn)行優(yōu)化,并確保每次訪問(wèn)該變量都從內(nèi)存讀取或?qū)懭搿?/p>

volatile用于處理多線程環(huán)境下共享數(shù)據(jù)可能發(fā)生的意外行為,例如信號(hào)處理、硬件寄存器等場(chǎng)景。

與Java中不同,C++的volatile關(guān)鍵字不能保證原子性、可見(jiàn)性或禁止重排序。

6、C語(yǔ)言中struct和union的區(qū)別

在C語(yǔ)言中,struct和union是兩種不同的復(fù)合數(shù)據(jù)類型,用于組織和存儲(chǔ)多個(gè)不同類型的變量。它們的主要區(qū)別如下:

結(jié)構(gòu)體(struct):

結(jié)構(gòu)體是一種能夠存儲(chǔ)不同類型數(shù)據(jù)成員的用戶自定義數(shù)據(jù)類型。

可以在結(jié)構(gòu)體中定義多個(gè)不同類型的成員變量,并可以通過(guò)點(diǎn)操作符來(lái)訪問(wèn)這些成員變量。

每個(gè)結(jié)構(gòu)體對(duì)象占據(jù)獨(dú)立的內(nèi)存空間,其大小為所有成員變量大小之和。

聯(lián)合體(union):

聯(lián)合體是一種特殊的數(shù)據(jù)類型,它允許使用相同的內(nèi)存空間來(lái)存儲(chǔ)不同類型的數(shù)據(jù)。

聯(lián)合體中可以定義多個(gè)成員變量,但只能同時(shí)存儲(chǔ)一個(gè)成員的值。

所有成員共享同一塊內(nèi)存空間,因此修改其中一個(gè)成員會(huì)影響其他成員。

聯(lián)合體適用于需要在不同類型之間進(jìn)行轉(zhuǎn)換或節(jié)省內(nèi)存空間的情況。

7、C++中struct和class的區(qū)別

在C++中,struct和class是兩種用于定義自定義數(shù)據(jù)類型的關(guān)鍵字。雖然它們的基本功能相似,但存在一些細(xì)微的區(qū)別:

默認(rèn)訪問(wèn)控制:

在struct中,默認(rèn)成員和繼承的訪問(wèn)級(jí)別是public。

在class中,默認(rèn)成員和繼承的訪問(wèn)級(jí)別是private。

成員函數(shù)默認(rèn)修飾符:

在struct中,成員函數(shù)默認(rèn)為public。

在class中,成員函數(shù)默認(rèn)為private。

繼承方式:

在struct和class中都可以使用公有、私有或受保護(hù)的繼承方式。

通常情況下,在面向?qū)ο缶幊讨?,使用class來(lái)表示實(shí)現(xiàn)封裝、繼承和多態(tài)的類。

使用習(xí)慣:

struct通常用于簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu)的定義,如存儲(chǔ)數(shù)據(jù)記錄或純粹地用于組織數(shù)據(jù)。

class更常用于封裝復(fù)雜對(duì)象及其相關(guān)操作,更符合面向?qū)ο缶幊田L(fēng)格。

8、數(shù)組和指針的區(qū)別

內(nèi)存分配:數(shù)組在定義時(shí)需要指定固定大小,內(nèi)存會(huì)在編譯時(shí)靜態(tài)分配。而指針沒(méi)有固定大小,可以動(dòng)態(tài)分配內(nèi)存。

數(shù)據(jù)訪問(wèn):數(shù)組使用下標(biāo)來(lái)訪問(wèn)元素,可以通過(guò)數(shù)組名加索引進(jìn)行訪問(wèn)。指針可以通過(guò)解引用操作符(*)或箭頭操作符(->)來(lái)訪問(wèn)指向的對(duì)象。

數(shù)組名與指針:數(shù)組名本質(zhì)上是一個(gè)常量指針,指向數(shù)組首個(gè)元素的地址。但數(shù)組名不能被賦值或修改。而指針變量可以被重新賦值指向不同的內(nèi)存地址。

函數(shù)參數(shù)傳遞:當(dāng)數(shù)組作為函數(shù)參數(shù)傳遞時(shí),實(shí)際上傳遞的是該數(shù)組首元素的地址。而指針可以直接作為函數(shù)參數(shù)傳遞,并改變?cè)紨?shù)據(jù)。

9、一個(gè)程序執(zhí)行的過(guò)程

編譯:源代碼經(jīng)過(guò)編譯器的處理,將其轉(zhuǎn)換成機(jī)器可執(zhí)行的二進(jìn)制代碼(目標(biāo)代碼)或者字節(jié)碼。

鏈接:如果程序中包含了外部引用的函數(shù)或變量,鏈接器將把這些符號(hào)連接到相應(yīng)的定義,生成最終可執(zhí)行文件。

加載:操作系統(tǒng)將可執(zhí)行文件加載到內(nèi)存中,并為其分配運(yùn)行所需的資源。

執(zhí)行:CPU按照指令序列依次執(zhí)行程序。每條指令包含特定的操作和操作數(shù),可以是算術(shù)運(yùn)算、邏輯判斷、內(nèi)存讀寫(xiě)等。

運(yùn)行時(shí)庫(kù)調(diào)用:程序在運(yùn)行時(shí)可能會(huì)調(diào)用一些庫(kù)函數(shù),如輸入輸出、內(nèi)存管理等。這些庫(kù)函數(shù)提供常用功能,方便開(kāi)發(fā)人員使用。

結(jié)束:當(dāng)程序完成所有指令并達(dá)到退出條件時(shí),程序結(jié)束運(yùn)行。操作系統(tǒng)回收相關(guān)資源,并返回給用戶相應(yīng)的結(jié)果或狀態(tài)信息。

10、C++中指針和用的區(qū)別

定義方式:指針使用*來(lái)聲明,并且需要通過(guò)取地址運(yùn)算符&獲取變量的地址;引用則直接以變量名定義。

空值:指針可以具有空值(nullptr),表示沒(méi)有指向有效對(duì)象;而引用必須始終引用一個(gè)有效的對(duì)象。

可改變性:指針可以被重新賦值,可以更改所指向的對(duì)象;而引用在創(chuàng)建時(shí)必須初始化,并且不能再綁定到其他對(duì)象上。

空間占用:指針本身占據(jù)額外的內(nèi)存空間來(lái)存儲(chǔ)地址;而引用僅作為已存在對(duì)象的別名,不占據(jù)額外空間。

訪問(wèn)方式:通過(guò)指針訪問(wèn)對(duì)象需要使用解引用操作符*;而通過(guò)引用直接訪問(wèn)即可,無(wú)需解引用操作符。

函數(shù)參數(shù)傳遞:指針可以作為函數(shù)參數(shù)傳遞,允許在函數(shù)內(nèi)部修改原始數(shù)據(jù);而引用也可以作為函數(shù)參數(shù)傳遞,但不會(huì)創(chuàng)建副本,在函數(shù)內(nèi)部修改將影響原始數(shù)據(jù)。

11、malloc/new. free/delete各自區(qū)別

分配方式:malloc()函數(shù)分配內(nèi)存時(shí)需要指定要分配的字節(jié)數(shù),返回一個(gè)void指針,需要進(jìn)行類型轉(zhuǎn)換;而new運(yùn)算符在分配內(nèi)存時(shí)會(huì)根據(jù)對(duì)象類型自動(dòng)計(jì)算所需字節(jié)數(shù),并返回指向正確類型的指針。

構(gòu)造函數(shù)調(diào)用:使用malloc()分配的內(nèi)存只是簡(jiǎn)單地獲取一塊原始內(nèi)存區(qū)域,不會(huì)調(diào)用對(duì)象的構(gòu)造函數(shù);而使用new運(yùn)算符分配的內(nèi)存會(huì)調(diào)用對(duì)象的構(gòu)造函數(shù)進(jìn)行初始化。

內(nèi)存越界檢查:使用 malloc() 分配內(nèi)存時(shí)沒(méi)有辦法進(jìn)行邊界檢查,容易出現(xiàn)緩沖區(qū)溢出等問(wèn)題;而 new[] 運(yùn)算符在分配數(shù)組時(shí)可以根據(jù)元素?cái)?shù)量進(jìn)行邊界檢查。

釋放方式:通過(guò) free() 釋放由 malloc() 分配的內(nèi)存;而使用 delete 運(yùn)算符釋放由 new 運(yùn)算符分配的單個(gè)對(duì)象所占用的內(nèi)存, 使用 delete[] 運(yùn)算符來(lái)釋放由 new[] 運(yùn)算符分配的數(shù)組所占用的內(nèi)存。

內(nèi)存對(duì)齊:malloc() 分配的內(nèi)存不保證按照特定對(duì)齊方式進(jìn)行,可能需要額外的對(duì)齊操作;而 new 和 new[] 運(yùn)算符可以確保正確的對(duì)齊方式。

12、 ++i與i++的區(qū)別

++i和i++都是C++中的自增運(yùn)算符,用于將變量增加1。它們之間的區(qū)別在于它們的返回值和執(zhí)行順序。

++i(前置自增):先進(jìn)行自增操作,然后返回自增后的值。

先對(duì)變量 i 進(jìn)行加1操作,再使用修改后的值。

例如,如果 i 的初始值為3,則 ++i 的結(jié)果為4,并且 i 的值也變?yōu)榱?。

i++(后置自增):先返回當(dāng)前值,然后再進(jìn)行自增操作。

先使用變量 i 當(dāng)前的值,在之后再對(duì)其進(jìn)行加1操作。

例如,如果 i 的初始值為3,則 i++ 的結(jié)果為3,并且 i 的值變?yōu)?。

在大多數(shù)情況下,這兩種形式在單獨(dú)使用時(shí)并沒(méi)有明顯區(qū)別。但當(dāng)它們作為表達(dá)式的一部分或者與其他運(yùn)算符結(jié)合時(shí),可能會(huì)產(chǎn)生不同的結(jié)果。例如:int i = 3;

int a = ++i; // 先將 i 加 1 再賦給 a,a 的值為 4

int b = i++; // 先將 i 賦給 b 再加 1,b 的值為 4

13、指針函數(shù)和函數(shù)指針的區(qū)別

指針函數(shù)(Pointer to a Function):

指針函數(shù)是一個(gè)返回指針類型的函數(shù)。它聲明了一個(gè)函數(shù),其返回類型是指向特定類型的指針。

通過(guò)使用指針函數(shù),我們可以間接地調(diào)用該函數(shù)并獲取其返回值。

示例:int* getPointer(); // 聲明一個(gè)返回int指針的指針函數(shù)

函數(shù)指針(Function Pointer):

函數(shù)指針是一個(gè)變量,用于存儲(chǔ)或指向特定類型的函數(shù)。

它可以將函數(shù)作為參數(shù)傳遞給其他函數(shù)、在運(yùn)行時(shí)動(dòng)態(tài)選擇要執(zhí)行的不同函數(shù)等。

使用函數(shù)指針,我們可以直接調(diào)用所存儲(chǔ)或指向的相應(yīng)函數(shù)。

示例:int add(int a, int b) { return a + b; }

int (*funcPtr)(int, int) = add; // 聲明一個(gè)名為 funcPtr 的整型返回值、接受兩個(gè)整型參數(shù)的函數(shù)指針,并將其初始化為 add 函數(shù)

14、指針數(shù)組和數(shù)組指針的區(qū)別

指針數(shù)組(Pointer Array):

指針數(shù)組是一個(gè)包含指針元素的數(shù)組。每個(gè)元素都是指向特定類型的指針。

在內(nèi)存中,指針數(shù)組會(huì)占據(jù)一段連續(xù)的空間,每個(gè)元素都存儲(chǔ)一個(gè)地址,可以分別指向不同的變量或?qū)ο蟆?/p>

示例:int* ptrArr[5]; // 聲明一個(gè)包含5個(gè)int類型指針元素的指針數(shù)組

數(shù)組指針(Array Pointer):

數(shù)組指針是一個(gè)指向數(shù)組的指針,也可以說(shuō)是一個(gè)具有特定數(shù)據(jù)類型的單個(gè)指針。

它存儲(chǔ)了數(shù)組第一個(gè)元素的地址,可以通過(guò)解引用操作符訪問(wèn)該數(shù)組的所有元素。

示例:int arr[5] = {1, 2, 3, 4, 5};

int (*arrPtr)[5] = &arr; // 聲明一個(gè)名為 arrPtr 的整型數(shù)組指針,并將其初始化為 arr 數(shù)組的地址

15、指針常量和常量指針的區(qū)別

指針常量(Pointer to Constant):

指針常量是一個(gè)指向常量對(duì)象的指針,這意味著該指針?biāo)赶虻膶?duì)象的值是不可修改的,但可以通過(guò)其他方式修改指針本身。

一旦指針被初始化為某個(gè)對(duì)象的地址,就不能再改變它所指向的對(duì)象了。

示例:const int* ptrToConst; // 聲明一個(gè)指向常量整數(shù)的指針

常量指針(Constant Pointer):

常量指針是一個(gè)不可更改地址綁定關(guān)系的指針,即該指針?biāo)鎯?chǔ)的地址不能再修改。但可以通過(guò)該指針間接地修改所指向?qū)ο蟮闹怠?/p>

這意味著可以更改所指向的對(duì)象,但不能更改存儲(chǔ)在該指針中的地址。int value = 10;

int* const constPtr = &value; // 聲明一個(gè)常量整型指針,并將其初始化為 value 的地址

16、值傳遞、指針傳遞引用傳遞的區(qū)別

值傳遞(Pass by Value):

在值傳遞中,函數(shù)接收到的是實(shí)際參數(shù)的副本。

函數(shù)對(duì)參數(shù)進(jìn)行修改不會(huì)影響原始數(shù)據(jù)。

優(yōu)點(diǎn)是簡(jiǎn)單、安全,不會(huì)對(duì)原始數(shù)據(jù)產(chǎn)生影響。

缺點(diǎn)是如果參數(shù)較大,復(fù)制數(shù)據(jù)的開(kāi)銷可能比較高。

指針傳遞(Pass by Pointer):

在指針傳遞中,函數(shù)接收到的是指向?qū)嶋H參數(shù)的指針。

函數(shù)可以通過(guò)該指針來(lái)訪問(wèn)和修改實(shí)際參數(shù)所在內(nèi)存地址上的數(shù)據(jù)。

優(yōu)點(diǎn)是可以在函數(shù)內(nèi)部修改實(shí)際參數(shù),并且避免了復(fù)制大量數(shù)據(jù)的開(kāi)銷。

缺點(diǎn)是需要額外處理空指針異常,并且需要顯式地使用解引用操作符。

引用傳遞(Pass by Reference):

在引用傳遞中,函數(shù)接收到的是實(shí)際參數(shù)的引用或別名。

函數(shù)可以直接使用該引用來(lái)訪問(wèn)和修改實(shí)際參數(shù)所在內(nèi)存地址上的數(shù)據(jù),就像操作原始數(shù)據(jù)一樣。

優(yōu)點(diǎn)是既可以在函數(shù)內(nèi)部修改實(shí)際參數(shù),又不需要顯式地使用解引用操作符。

缺點(diǎn)是一旦傳遞了引用,就無(wú)法避免修改原始數(shù)據(jù)。

17、extern “c”的作用

在C++中,extern "C"是用于指定一個(gè)函數(shù)或變量采用C語(yǔ)言的編譯規(guī)則進(jìn)行編譯和鏈接。當(dāng)在C++代碼中調(diào)用C語(yǔ)言編寫(xiě)的函數(shù)時(shí),由于C和C++對(duì)函數(shù)名稱的命名規(guī)則存在差異,使用extern "C"可以告訴編譯器按照C語(yǔ)言的命名規(guī)則來(lái)處理該函數(shù),以保證正確鏈接。

具體而言,使用extern "C"聲明的函數(shù)會(huì)按照C語(yǔ)言的命名約定進(jìn)行編譯和鏈接,即不會(huì)進(jìn)行名稱修飾(name mangling),函數(shù)名與在C語(yǔ)言中定義的一致。這樣,在C++代碼中就可以直接通過(guò)函數(shù)名調(diào)用該函數(shù),而無(wú)需考慮名稱修飾帶來(lái)的問(wèn)題。

18、大端對(duì)擠與小端對(duì)擠

大端序(Big-Endian)和小端序(Little-Endian): 大端序是指數(shù)據(jù)的高字節(jié)存儲(chǔ)在低地址,而小端序則是指數(shù)據(jù)的低字節(jié)存儲(chǔ)在低地址。例如,十六進(jìn)制數(shù)0x12345678在大端序中以字節(jié)形式存儲(chǔ)為12 34 56 78,在小端序中則存儲(chǔ)為78 56 34 12。不同的處理器架構(gòu)可能采用不同的字節(jié)順序。

對(duì)齊填充(Padding): 在結(jié)構(gòu)體或類定義中,為了滿足對(duì)齊要求,編譯器可能會(huì)在結(jié)構(gòu)體或類成員之間插入額外的空白字節(jié),稱為對(duì)齊填充。這樣做可以提高內(nèi)存訪問(wèn)效率,避免因未對(duì)齊訪問(wèn)造成性能損失。 在默認(rèn)情況下,一般采用4字節(jié)或8字節(jié)對(duì)齊。例如,在32位系統(tǒng)上定義一個(gè)結(jié)構(gòu)體成員變量為int類型,則該成員變量會(huì)被自動(dòng)放置到4字節(jié)邊界上,并且后面可能有3個(gè)填充字節(jié)。

19、深拷貝、淺拷貝、寫(xiě)時(shí)拷貝后端技術(shù)

深拷貝(Deep Copy)和淺拷貝(Shallow Copy)是常用于數(shù)據(jù)復(fù)制的概念,而寫(xiě)時(shí)拷貝(Copy-on-Write)是一種優(yōu)化技術(shù)。這些概念通常與后端技術(shù)無(wú)直接關(guān)聯(lián),但可以在各種后端技術(shù)中使用。

深拷貝(Deep Copy): 深拷貝是指創(chuàng)建一個(gè)新對(duì)象,將源對(duì)象的所有成員變量逐個(gè)復(fù)制到新對(duì)象中,并且對(duì)引用類型的成員變量也進(jìn)行遞歸地復(fù)制。結(jié)果是兩個(gè)對(duì)象具有相同的值,但在內(nèi)存中完全獨(dú)立存在。修改其中一個(gè)對(duì)象不會(huì)影響另一個(gè)對(duì)象。 深拷貝通常涉及到自定義的拷貝構(gòu)造函數(shù)或重載賦值運(yùn)算符。

淺拷貝(Shallow Copy): 淺拷貝是指創(chuàng)建一個(gè)新對(duì)象,將源對(duì)象的所有成員變量簡(jiǎn)單地復(fù)制到新對(duì)象中。如果成員變量是引用類型,則只復(fù)制了引用而不是實(shí)際數(shù)據(jù)。結(jié)果是兩個(gè)對(duì)象共享同一份數(shù)據(jù),在某些情況下可能導(dǎo)致意外修改。

寫(xiě)時(shí)拷貝(Copy-on-Write): 寫(xiě)時(shí)拷貝是一種內(nèi)存管理優(yōu)化技術(shù),在需要修改被共享的數(shù)據(jù)時(shí)才執(zhí)行實(shí)際的復(fù)制操作。當(dāng)多個(gè)對(duì)象共享同一份數(shù)據(jù)時(shí),如果有一個(gè)對(duì)象要修改該數(shù)據(jù),就會(huì)先進(jìn)行復(fù)制操作,將數(shù)據(jù)的副本創(chuàng)建出來(lái),然后再進(jìn)行修改。這樣可以減少不必要的內(nèi)存復(fù)制開(kāi)銷,并提高性能。

這些概念在后端技術(shù)中的應(yīng)用取決于具體的場(chǎng)景和需求。例如,在并發(fā)編程中,可以使用寫(xiě)時(shí)拷貝來(lái)避免多線程競(jìng)爭(zhēng)導(dǎo)致的數(shù)據(jù)沖突。在分布式系統(tǒng)中,深拷貝和淺拷貝可能用于傳遞對(duì)象或消息。對(duì)于數(shù)據(jù)庫(kù)備份等情況,可能需要考慮深拷貝或淺拷貝以及相關(guān)的持久化技術(shù)。

20、什么是C++的基本數(shù)據(jù)類型?

整型(Integral Types):

bool:布爾類型,用于表示真或假。

char:字符類型,表示單個(gè)字符。

int:整數(shù)類型,表示帶符號(hào)整數(shù)。

unsigned int:無(wú)符號(hào)整數(shù)類型,表示非負(fù)整數(shù)。

short:短整數(shù)類型,表示較小范圍的帶符號(hào)整數(shù)。

unsigned short:無(wú)符號(hào)短整數(shù)類型,表示較小范圍的非負(fù)整數(shù)。

long:長(zhǎng)整數(shù)類型,表示較大范圍的帶符號(hào)整數(shù)。

unsigned long:無(wú)符號(hào)長(zhǎng)整數(shù)類型,表示較大范圍的非負(fù)整數(shù)。

浮點(diǎn)型(Floating-point Types):

float:?jiǎn)尉雀↑c(diǎn)型,用于存儲(chǔ)小數(shù)。

double:雙精度浮點(diǎn)型,在范圍和精度上比f(wàn)loat更大。

枚舉型(Enumeration Types):

enum:枚舉類型,用于定義一組具名常量值。

字符串型(Character Types):

char[] 或 char* :字符串類型,用于存儲(chǔ)一系列字符。

除了這些基本數(shù)據(jù)類型外,C++還支持一些復(fù)合數(shù)據(jù)類型如數(shù)組、結(jié)構(gòu)體、聯(lián)合體和指針等。此外,在標(biāo)準(zhǔn)庫(kù)中也提供了許多其他數(shù)據(jù)結(jié)構(gòu)和容器類,如向量、列表、映射等。這些數(shù)據(jù)類型和容器類可用于構(gòu)建更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和算法。

21、解釋C++中的引用(Reference)和指針(Pointer)之間的區(qū)別。

定義和使用:引用在聲明時(shí)必須被初始化,并且一旦綁定到一個(gè)對(duì)象后,就無(wú)法重新綁定到另一個(gè)對(duì)象。而指針可以先聲明,再通過(guò)賦值操作指向不同的對(duì)象。

空值(Null value):引用不允許為空,必須始終引用有效的對(duì)象。而指針可以為空,在某些情況下可以表示沒(méi)有有效對(duì)象。

內(nèi)存地址:引用沒(méi)有自己的內(nèi)存地址,它只是作為已存在對(duì)象的別名。而指針有自己的內(nèi)存地址,并且可以直接對(duì)其進(jìn)行操作。

操作符:對(duì)于引用,使用操作符“&”獲取變量的地址并創(chuàng)建引用;使用操作符“”來(lái)解引用(取得所引用對(duì)象的值)。而對(duì)于指針,則使用操作符“&”來(lái)獲取變量地址;使用操作符“”來(lái)解引用以獲得該指針?biāo)赶蛭恢蒙洗鎯?chǔ)的值。

可以更改性:由于引用只是一個(gè)別名,一旦與某個(gè)變量綁定后,通過(guò)該引用可以修改該變量的值。而指針本身是一個(gè)獨(dú)立實(shí)體,在不斷地進(jìn)行賦值、移動(dòng)等操作下,可以改變所指向的對(duì)象。

22、什么是函數(shù)重載(Function Overloading)?如何實(shí)現(xiàn)函數(shù)重載?

函數(shù)重載(Function Overloading)是指在同一個(gè)作用域內(nèi),允許定義多個(gè)具有相同名稱但參數(shù)類型、參數(shù)順序或參數(shù)個(gè)數(shù)不同的函數(shù)。通過(guò)函數(shù)重載,可以使用相同的函數(shù)名來(lái)實(shí)現(xiàn)不同功能的函數(shù)。

要實(shí)現(xiàn)函數(shù)重載,需要遵循以下規(guī)則:

函數(shù)名稱必須相同。

參數(shù)列表必須不同:可以通過(guò)參數(shù)的類型、順序或個(gè)數(shù)進(jìn)行區(qū)分。

返回類型通常不是區(qū)分函數(shù)重載的標(biāo)準(zhǔn),所以不能僅通過(guò)返回類型來(lái)進(jìn)行重載。

示例代碼如下:// 函數(shù)重載示例

// 兩個(gè)整數(shù)相加

int add(int a, int b) {

return a + b;

}

// 三個(gè)整數(shù)相加

int add(int a, int b, int c) {

return a + b + c;

}

// 兩個(gè)浮點(diǎn)數(shù)相加

float add(float a, float b) {

return a + b;

}

int main() {

int sum1 = add(3, 5); // 調(diào)用第一個(gè)add函數(shù)

int sum2 = add(2, 4, 6); // 調(diào)用第二個(gè)add函數(shù)

float sum3 = add(1.5f, 2.7f); // 調(diào)用第三個(gè)add函數(shù)

return 0;

}

在上面的示例中,add() 函數(shù)被重載了三次,根據(jù)傳入的參數(shù)類型和數(shù)量,編譯器能夠確定要調(diào)用哪個(gè)具體的函數(shù)。通過(guò)函數(shù)重載,可以提高代碼的可讀性和靈活性,使得函數(shù)命名更加直觀且符合語(yǔ)義。

23、解釋什么是類和對(duì)象,以及它們之間的關(guān)系。

在面向?qū)ο缶幊讨?,類和?duì)象是兩個(gè)核心概念。

類(Class)是一種抽象的數(shù)據(jù)類型,它定義了一組屬性和方法,用于描述具有相似特征和行為的對(duì)象。類可以看作是一個(gè)模板或藍(lán)圖,描述了如何創(chuàng)建對(duì)象。

對(duì)象(Object)是類的實(shí)例化結(jié)果,它是具體存在的、能夠存儲(chǔ)數(shù)據(jù)和執(zhí)行操作的實(shí)體。每個(gè)對(duì)象都有自己獨(dú)立的狀態(tài)(屬性值)和行為(方法)。

關(guān)系方面:

類是抽象的概念,用于定義對(duì)象的共同屬性和行為。它們通常由變量(成員變量)和函數(shù)(成員函數(shù)/方法)組成。

對(duì)象是類的具體實(shí)例,根據(jù)類的定義而創(chuàng)建。通過(guò)使用關(guān)鍵字 new 來(lái)分配內(nèi)存空間并初始化一個(gè)新的對(duì)象。

類可以看作是對(duì)象構(gòu)造的模板或原型,通過(guò)實(shí)例化來(lái)生成多個(gè)具有相似特征和行為的對(duì)象。

通過(guò)使用類中定義的屬性和方法,我們可以操作對(duì)象并訪問(wèn)其狀態(tài)。

簡(jiǎn)單來(lái)說(shuō),類定義了一種抽象數(shù)據(jù)類型,并提供了對(duì)應(yīng)實(shí)例化后具體存在的對(duì)象所需的結(jié)構(gòu)和行為。通過(guò)創(chuàng)建多個(gè)不同的對(duì)象,我們可以同時(shí)處理各種不同數(shù)據(jù)并執(zhí)行相關(guān)操作。

24、C++中的訪問(wèn)修飾符有哪些?請(qǐng)解釋它們分別的作用。

public:

公共成員在任何地方都可以被訪問(wèn)。

類的公共成員可以通過(guò)對(duì)象直接訪問(wèn)或者通過(guò)類的公共接口進(jìn)行訪問(wèn)。

公共成員通常用于描述對(duì)象的行為或提供公開(kāi)的數(shù)據(jù)。

protected:

受保護(hù)成員只能在當(dāng)前類及其派生類中被訪問(wèn)。

外部代碼無(wú)法直接訪問(wèn)受保護(hù)成員,但派生類可以繼承并訪問(wèn)這些成員。

受保護(hù)成員通常用于封裝一些內(nèi)部實(shí)現(xiàn)細(xì)節(jié),子類需要使用但不希望被其他外部代碼直接訪問(wèn)。

private:

私有成員只能在當(dāng)前類內(nèi)部被訪問(wèn)。

外部代碼無(wú)法直接訪問(wèn)私有成員,包括派生類。

私有成員通常用于封裝和隱藏實(shí)現(xiàn)細(xì)節(jié),限制對(duì)數(shù)據(jù)的直接操作。

25、什么是虛函數(shù)(Virtual Function)和純虛函數(shù)(Pure Virtual Function)?有什么區(qū)別?

在C++中,虛函數(shù)(Virtual Function)是一種用于實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)的特殊函數(shù)。它通過(guò)使用關(guān)鍵字virtual進(jìn)行聲明,在基類中定義并在派生類中進(jìn)行重寫(xiě)。當(dāng)通過(guò)基類指針或引用調(diào)用虛函數(shù)時(shí),將根據(jù)實(shí)際對(duì)象的類型來(lái)確定要調(diào)用的函數(shù)版本。

純虛函數(shù)(Pure Virtual Function)是一個(gè)在基類中聲明但沒(méi)有具體實(shí)現(xiàn)的虛函數(shù)。它通過(guò)在函數(shù)聲明末尾加上= 0來(lái)表示純虛函數(shù)。純虛函數(shù)只有聲明而沒(méi)有定義,需要被派生類重寫(xiě)才能使用。

區(qū)別:

虛函數(shù)可以具有默認(rèn)實(shí)現(xiàn),而純虛函數(shù)沒(méi)有具體實(shí)現(xiàn)。

派生類可以選擇是否重寫(xiě)虛函數(shù),但必須重寫(xiě)純虛函數(shù)。

含有純虛函數(shù)的類稱為抽象類,不能直接創(chuàng)建對(duì)象,只能作為基類供派生類繼承和實(shí)現(xiàn)。而含有普通虛函數(shù)的類可以被直接實(shí)例化。

如果一個(gè)派生類未覆蓋了其基類的純虛函數(shù),則該派生類也成為抽象類。

26、解釋C++中的繼承(Inheritance),包括單繼承和多繼承。

在C++中,繼承(Inheritance)是一種面向?qū)ο缶幊痰母拍?,用于?chuàng)建一個(gè)新的類(稱為派生類或子類),從一個(gè)或多個(gè)現(xiàn)有的類(稱為基類或父類)繼承屬性和行為。

單繼承(Single Inheritance)指的是一個(gè)派生類只能從一個(gè)基類繼承屬性和行為。語(yǔ)法上使用關(guān)鍵字class后面跟著冒號(hào)來(lái)指定繼承關(guān)系,并且可以選擇公有繼承、私有繼承或保護(hù)繼承。例如:class Base {

public:

// 基類成員函數(shù)和成員變量

};

class Derived : public Base {

// 派生類成員函數(shù)和成員變量

};

多繼承(Multiple Inheritance)指的是一個(gè)派生類可以從多個(gè)基類繼承屬性和行為。在語(yǔ)法上,通過(guò)使用逗號(hào)將多個(gè)基類名稱放在冒號(hào)后面來(lái)表示多重繼承關(guān)系。例如:class Base1 {

public:

// 基類1成員函數(shù)和成員變量

};

class Base2 {

public:

// 基類2成員函數(shù)和成員變量

};

class Derived : public Base1, public Base2 {

// 派生類成員函數(shù)和成員變量

};

通過(guò)繼承,派生類可以獲得基類的非私有成員函數(shù)和成員變量,并且可以在派生類中添加新的成員函數(shù)和成員變量,或者重寫(xiě)基類的虛函數(shù)。

繼承實(shí)現(xiàn)了代碼重用和層次化設(shè)計(jì),使得對(duì)象之間的關(guān)系更加清晰。但是需要注意合理使用繼承,避免過(guò)度復(fù)雜的繼承關(guān)系和潛在的問(wèn)題,比如菱形繼承(Diamond Inheritance)引發(fā)的二義性等。

27、請(qǐng)解釋析構(gòu)函數(shù)(Destructor)在C++中的作用和使用方式。

析構(gòu)函數(shù)(Destructor)是在對(duì)象銷毀時(shí)被自動(dòng)調(diào)用的特殊成員函數(shù)。它的主要作用是完成對(duì)象的清理工作,釋放對(duì)象占用的資源,以及執(zhí)行必要的善后操作。

在C++中,析構(gòu)函數(shù)使用類名前加上一個(gè)波浪線(~)來(lái)定義,沒(méi)有返回類型和參數(shù)列表。每個(gè)類只能有一個(gè)析構(gòu)函數(shù),并且不接受任何參數(shù)。例如:class MyClass {

public:

// 構(gòu)造函數(shù)

MyClass() {

// 初始化工作

}

// 析構(gòu)函數(shù)

~MyClass() {

// 清理工作、釋放資源等

}

};

當(dāng)對(duì)象超出其作用域、被顯式刪除或者程序結(jié)束時(shí),析構(gòu)函數(shù)會(huì)自動(dòng)被調(diào)用。它可以處理一些需要在對(duì)象銷毀時(shí)進(jìn)行的清理操作,比如釋放動(dòng)態(tài)分配的內(nèi)存、關(guān)閉文件、斷開(kāi)網(wǎng)絡(luò)連接等。

注意,在C++中如果沒(méi)有顯式定義析構(gòu)函數(shù),編譯器會(huì)提供默認(rèn)的析構(gòu)函數(shù),默認(rèn)析構(gòu)函數(shù)什么也不做。但如果需要在對(duì)象銷毀時(shí)執(zhí)行一些特殊操作或釋放資源,則應(yīng)該顯式定義自己的析構(gòu)函數(shù)。

28、C++中的友元函數(shù)(Friend Function)是什么?為什么會(huì)使用它們?

在C++中,友元函數(shù)(Friend Function)是一種被聲明為某個(gè)類的友元的非成員函數(shù)。這意味著友元函數(shù)可以直接訪問(wèn)該類的私有成員和保護(hù)成員。

友元函數(shù)通過(guò)在類中進(jìn)行聲明并在類外部進(jìn)行定義來(lái)實(shí)現(xiàn)。聲明方式為將該函數(shù)放置在類的聲明中,并在前面加上friend關(guān)鍵字,表示它是該類的友元。定義時(shí)不需要使用作用域解析運(yùn)算符(::),因?yàn)樗皇窃擃惖某蓡T函數(shù)。

使用友元函數(shù)有以下幾個(gè)原因:

訪問(wèn)私有成員:友元函數(shù)能夠直接訪問(wèn)包含它們的類的私有成員和保護(hù)成員,這對(duì)于需要操作或讀取對(duì)象內(nèi)部數(shù)據(jù)但又無(wú)法作為成員函數(shù)實(shí)現(xiàn)的情況很有用。

增強(qiáng)封裝性:通常情況下,我們應(yīng)該將數(shù)據(jù)隱藏在類的私有部分,并提供公共接口來(lái)操作數(shù)據(jù)。但某些特殊情況下可能需要授權(quán)其他非成員函數(shù)訪問(wèn)私有數(shù)據(jù),而不暴露給外界。這時(shí)候可以使用友元函數(shù),在限定范圍內(nèi)增強(qiáng)封裝性。

實(shí)現(xiàn)運(yùn)算符重載:運(yùn)算符重載通常涉及兩個(gè)對(duì)象之間的操作,而且其中一個(gè)對(duì)象可能不是調(diào)用者。通過(guò)將重載運(yùn)算符的非成員函數(shù)聲明為友元函數(shù),可以實(shí)現(xiàn)對(duì)私有數(shù)據(jù)的訪問(wèn),并使運(yùn)算符重載更加靈活。

需要注意的是,友元函數(shù)不屬于類的成員函數(shù),它們沒(méi)有隱含的this指針,因此無(wú)法直接訪問(wèn)非靜態(tài)成員變量。但它們可以通過(guò)對(duì)象的參數(shù)來(lái)訪問(wèn)成員變量和調(diào)用其他成員函數(shù)。

29、解釋命名空間(Namespace)在C++中的作用和優(yōu)勢(shì)。

命名空間(Namespace)是C++中一種用于組織代碼的機(jī)制,可以將全局作用域劃分為不同的區(qū)域,以避免命名沖突,并提供更好的代碼結(jié)構(gòu)和可讀性。

以下是命名空間在C++中的作用和優(yōu)勢(shì):

避免命名沖突:當(dāng)我們?cè)诰帉?xiě)大型程序或使用多個(gè)庫(kù)時(shí),可能會(huì)出現(xiàn)相同名稱的函數(shù)、變量或類等。使用命名空間可以將這些實(shí)體包裝到特定的命名空間中,在不同的命名空間中定義相同名稱的實(shí)體不會(huì)產(chǎn)生沖突。

提供更好的代碼結(jié)構(gòu):通過(guò)將相關(guān)功能或模塊放置在相應(yīng)的命名空間下,可以提供更清晰、組織良好的代碼結(jié)構(gòu)。這使得代碼易于理解、維護(hù)和擴(kuò)展。

支持重載和擴(kuò)展:使用命名空間可以支持函數(shù)、類等實(shí)體的重載。當(dāng)我們需要為相似但功能稍有差異的對(duì)象創(chuàng)建多個(gè)版本時(shí),可以利用命名空間來(lái)區(qū)分它們,并根據(jù)需要進(jìn)行選擇調(diào)用。

具備嵌套性:C++中的命名空間可以嵌套定義,即在一個(gè)命名空間內(nèi)部可以再定義其他子命名空間。這樣可以進(jìn)一步劃分和組織相關(guān)聯(lián)的代碼。

可避免全局污染:使用命名空間可以減少全局命名的使用,從而減少全局作用域的變量和函數(shù)的數(shù)量。這有助于避免不必要的全局變量和函數(shù)污染。

提高可讀性和可維護(hù)性:通過(guò)明確指定實(shí)體所屬的命名空間,代碼的可讀性得到提高。開(kāi)發(fā)人員可以更清楚地知道特定實(shí)體是在哪個(gè)命名空間下定義和使用的,從而增強(qiáng)了代碼的可維護(hù)性。

30、什么是模板(Template)?如何定義一個(gè)模板類或模板函數(shù)?

模板(Template)是C++中的一種泛型編程機(jī)制,允許定義通用的類或函數(shù),可以在多個(gè)不同類型上進(jìn)行實(shí)例化。通過(guò)使用模板,可以實(shí)現(xiàn)代碼重用和提供靈活性。

下面是如何定義一個(gè)模板類或模板函數(shù)的示例:

定義一個(gè)模板類:template

class MyClass {

public:

T data;

void display() {

std::cout << "Data: " << data << std::endl;

}

};

在上述示例中,我們使用template來(lái)聲明一個(gè)模板類,并通過(guò)typename T指定了一個(gè)類型參數(shù)。這樣,MyClass就可以在不同的類型上進(jìn)行實(shí)例化。

定義一個(gè)模板函數(shù):template

T getMax(T a, T b) {

return (a > b) ? a : b;

}

在上述示例中,我們使用template來(lái)聲明一個(gè)模板函數(shù),并通過(guò)typename T指定了一個(gè)類型參數(shù)。這樣,getMax()就可以接收不同類型的參數(shù)并返回較大的值。

使用時(shí),可以按照以下方式對(duì)模板進(jìn)行實(shí)例化和調(diào)用:MyClassobj; // 實(shí)例化為int類型的MyClass對(duì)象

obj.data = 10;

obj.display();

int result = getMax(5, 8); // 調(diào)用getMax函數(shù)并傳入int型參數(shù)

std::cout << "Max value: " << result << std::endl;

通過(guò)模板,我們可以在編寫(xiě)代碼時(shí)不需要為每個(gè)特定類型都重復(fù)編寫(xiě)類或函數(shù)的定義,而是使用通用的模板進(jìn)行實(shí)例化。這提供了更高的代碼重用性和靈活性。

31、C++標(biāo)準(zhǔn)模板庫(kù)(STL)中的常用容器有哪些?請(qǐng)解釋它們的特點(diǎn)和使用場(chǎng)景。

vector:

特點(diǎn):動(dòng)態(tài)數(shù)組,支持快速隨機(jī)訪問(wèn)元素,并且能夠在末尾進(jìn)行高效插入和刪除操作。

使用場(chǎng)景:適用于需要頻繁進(jìn)行隨機(jī)訪問(wèn)、動(dòng)態(tài)調(diào)整大小以及在末尾添加或刪除元素的情況。

list:

特點(diǎn):雙向鏈表,支持快速在任意位置插入和刪除元素,但不支持隨機(jī)訪問(wèn)。

使用場(chǎng)景:適用于需要頻繁在任意位置插入和刪除元素的情況,但不需要隨機(jī)訪問(wèn)元素。

deque:

特點(diǎn):雙端隊(duì)列,可以在兩端高效地進(jìn)行插入和刪除操作,支持隨機(jī)訪問(wèn)。

使用場(chǎng)景:適用于需要在兩端進(jìn)行頻繁插入和刪除操作,并且可能需要隨機(jī)訪問(wèn)元素的情況。

stack:

特點(diǎn):后進(jìn)先出(LIFO)的堆棧結(jié)構(gòu),只能在棧頂進(jìn)行插入和刪除操作。

使用場(chǎng)景:適用于需要實(shí)現(xiàn)后進(jìn)先出策略的問(wèn)題,如函數(shù)調(diào)用棧、括號(hào)匹配等。

queue:

特點(diǎn):先進(jìn)先出(FIFO)的隊(duì)列結(jié)構(gòu),只能在隊(duì)尾進(jìn)行插入,在隊(duì)首進(jìn)行刪除操作。

使用場(chǎng)景:適用于需要實(shí)現(xiàn)先進(jìn)先出策略的問(wèn)題,如任務(wù)調(diào)度、消息隊(duì)列等。

priority_queue:

特點(diǎn):基于堆結(jié)構(gòu)實(shí)現(xiàn)的優(yōu)先隊(duì)列,可以按照指定的優(yōu)先級(jí)順序插入和訪問(wèn)元素。

使用場(chǎng)景:適用于需要按照特定優(yōu)先級(jí)處理元素的情況,如任務(wù)調(diào)度、最小/最大值查找等。

map:

特點(diǎn):關(guān)聯(lián)容器,提供鍵值對(duì)存儲(chǔ),并按照鍵的有序性進(jìn)行排序和訪問(wèn)。

使用場(chǎng)景:適用于需要快速根據(jù)鍵查找對(duì)應(yīng)值的情況,并且需要保持有序性。

set:

特點(diǎn):關(guān)聯(lián)容器,提供有序唯一元素集合,不允許重復(fù)元素。

使用場(chǎng)景:適用于需要維護(hù)有序且無(wú)重復(fù)元素集合的情況。

這些容器都是通過(guò)模板類實(shí)現(xiàn)的,并提供了一系列成員函數(shù)來(lái)支持常見(jiàn)操作。根據(jù)具體需求選擇合適的容器可以提高代碼效率和可讀性。

32、解釋什么是異常處理(Exception Handling),以及try-catch塊的工作原理。

異常處理(Exception Handling)是一種編程技術(shù),用于在程序執(zhí)行過(guò)程中捕獲和處理出現(xiàn)的異常情況,以保證程序的穩(wěn)定性和可靠性。

在C++中,異常處理通過(guò)try-catch塊來(lái)實(shí)現(xiàn)。try塊用于包含可能拋出異常的代碼片段,而catch塊則用于捕獲并處理這些異常。其工作原理如下:

在try塊內(nèi)部,程序執(zhí)行可能引發(fā)異常的語(yǔ)句。

如果在try塊中發(fā)生了異常,那么會(huì)立即跳轉(zhuǎn)到與之匹配的catch塊。

catch塊中列出了要捕獲的特定類型或通用類型的異常。當(dāng)匹配到對(duì)應(yīng)類型的異常時(shí),相應(yīng)的catch塊將被執(zhí)行。

執(zhí)行完匹配的catch塊后,程序?qū)⒗^續(xù)執(zhí)行接下來(lái)的代碼。

catch塊可以有多個(gè),并按照順序進(jìn)行匹配檢查。如果某個(gè)catch塊成功匹配了異常類型,則該catch塊會(huì)被執(zhí)行;如果沒(méi)有找到匹配項(xiàng),則該異常會(huì)傳遞給上一層調(diào)用函數(shù)或者系統(tǒng)默認(rèn)處理。

通常,在catch塊中可以對(duì)捕獲到的異常進(jìn)行必要的處理操作,比如輸出錯(cuò)誤信息、進(jìn)行修復(fù)操作或者重新拋出其他更高級(jí)別的異常。

使用try-catch語(yǔ)句能夠有效地處理程序運(yùn)行時(shí)可能發(fā)生的各種異常情況,從而提高程序的健壯性和可維護(hù)性。

33、C++中的運(yùn)算符重載(Operator Overloading)是什么?如何實(shí)現(xiàn)運(yùn)算符重載?

C++中的運(yùn)算符重載(Operator Overloading)是一種特性,允許程序員為已有的運(yùn)算符賦予新的含義或行為,以適應(yīng)自定義類型的操作需求。通過(guò)運(yùn)算符重載,可以實(shí)現(xiàn)對(duì)用戶自定義類型對(duì)象之間的運(yùn)算進(jìn)行重定義。

運(yùn)算符重載使用特定的語(yǔ)法和函數(shù)來(lái)定義,具體步驟如下:

創(chuàng)建一個(gè)成員函數(shù)或非成員函數(shù)來(lái)實(shí)現(xiàn)運(yùn)算符重載。該函數(shù)應(yīng)包含所要重載的運(yùn)算符及其參數(shù)。

選擇合適的重載形式:一元操作符(只有一個(gè)操作數(shù))或二元操作符(兩個(gè)操作數(shù))。

根據(jù)需要,在函數(shù)內(nèi)部實(shí)現(xiàn)相應(yīng)的操作邏輯,并返回結(jié)果。

以下是示例代碼演示如何通過(guò)運(yùn)算符重載實(shí)現(xiàn)矢量加法:#include

class Vector {

private:

double x, y;

public:

Vector(double xVal = 0, double yVal = 0) : x(xVal), y(yVal) {}

Vector operator+(const Vector& other) const {

return Vector(x + other.x, y + other.y);

}

void display() const {

std::cout << "(" << x << ", " << y << ")" << std::endl;

}

};

int main() {

Vector v1(2, 3);

Vector v2(4, 5);

Vector result = v1 + v2;

result.display(); // 輸出 (6, 8)

return 0;

}

在上述代碼中,我們定義了一個(gè)名為Vector的類,并重載了加法運(yùn)算符+。通過(guò)實(shí)現(xiàn)成員函數(shù)operator+,我們可以使用v1 + v2來(lái)執(zhí)行矢量的加法操作。

34、請(qǐng)解釋虛擬繼承(Virtual Inheritance)在多繼承中的作用和意義。

在多繼承中,如果一個(gè)派生類從多個(gè)基類繼承同一份虛基類,那么這些基類將共享同一個(gè)實(shí)例。這種繼承方式稱為虛擬繼承(Virtual Inheritance)。

虛擬繼承的作用和意義主要體現(xiàn)在解決"菱形繼承"(Diamond Inheritance)問(wèn)題。菱形繼承指的是當(dāng)一個(gè)派生類同時(shí)從兩個(gè)不相關(guān)的基類派生,并且這兩個(gè)基類又公共地繼承自同一個(gè)基類,從而導(dǎo)致派生類中包含了兩份相同的基類數(shù)據(jù)成員。

使用虛擬繼承可以避免菱形繼承問(wèn)題帶來(lái)的二義性和資源浪費(fèi)。它通過(guò)在共同基類上設(shè)置虛擬關(guān)鍵字來(lái)標(biāo)識(shí)該基類是虛基類,被直接派生的每個(gè)派生類只保留對(duì)共同虛基類的單一實(shí)例引用。這樣,即使多個(gè)路徑都指向同一份虛基類,也只有一份實(shí)例存在于最后的派生對(duì)象中。

以下是示例代碼演示了虛擬繼承解決菱形繼承問(wèn)題:#include

class Animal {

public:

Animal() { std::cout << "Animal constructor called." << std::endl; }

int age;

};

class Mammal : public virtual Animal {

public:

Mammal() { std::cout << "Mammal constructor called." << std::endl; }

};

class Bird : public virtual Animal {

public:

Bird() { std::cout << "Bird constructor called." << std::endl; }

};

class Platypus : public Mammal, public Bird {

public:

Platypus() { std::cout << "Platypus constructor called." << std::endl; }

};

int main() {

Platypus platypus;

platypus.age = 10;

std::cout << "Platypus age: " << platypus.age << std::endl;

return 0;

}

在上述代碼中,Animal是虛基類,Mammal和Bird都通過(guò)虛擬繼承繼承自Animal。最后,Platypus派生自Mammal和Bird。

使用虛擬繼承可以確保Platypus類只有一個(gè)Animal實(shí)例,避免了菱形繼承問(wèn)題。同時(shí),它還減少了內(nèi)存占用和構(gòu)造函數(shù)的調(diào)用次數(shù)。

35、解釋C++中的類型轉(zhuǎn)換操作符(Type Conversion Operator)和顯式類型轉(zhuǎn)換(Explicit Type Casting)。

在C++中,類型轉(zhuǎn)換操作符和顯式類型轉(zhuǎn)換是用于將一個(gè)類型的值轉(zhuǎn)換為另一種類型的機(jī)制。

類型轉(zhuǎn)換操作符(Type Conversion Operator): 類型轉(zhuǎn)換操作符是一種特殊的成員函數(shù),它被用來(lái)定義自定義類型到其他類型的隱式轉(zhuǎn)換。它以類似于函數(shù)調(diào)用的方式使用,并返回目標(biāo)類型的值。通過(guò)重載該操作符,可以讓用戶自定義對(duì)象在不同數(shù)據(jù)類型之間進(jìn)行隱式轉(zhuǎn)換。

示例代碼如下所示:class MyInt {

private:

int value;

public:

MyInt(int v) : value(v) {}

operator int() { // 定義了從 MyInt 到 int 的隱式轉(zhuǎn)換

return value;

}

};

int main() {

MyInt myInt(42);

int num = myInt; // 調(diào)用隱式轉(zhuǎn)換操作符將 MyInt 轉(zhuǎn)換為 int

return 0;

}

顯式類型轉(zhuǎn)換(Explicit Type Casting): 顯式類型轉(zhuǎn)換是指通過(guò)強(qiáng)制指定要進(jìn)行的具體類型轉(zhuǎn)換來(lái)將一個(gè)值從一種數(shù)據(jù)類型轉(zhuǎn)換為另一種數(shù)據(jù)類型。C++提供了幾種顯式類型轉(zhuǎn)換運(yùn)算符:

靜態(tài)/常規(guī)強(qiáng)制(Static/Regular Cast):使用 static_cast 進(jìn)行常規(guī)的強(qiáng)制類型轉(zhuǎn)換。

動(dòng)態(tài)強(qiáng)制(Dynamic Cast):使用 dynamic_cast 進(jìn)行類層次間的向下轉(zhuǎn)換,用于處理多態(tài)類型。

重新解釋強(qiáng)制(Reinterpret Cast):使用 reinterpret_cast 進(jìn)行底層二進(jìn)制的重新解釋,可以將任意指針類型相互轉(zhuǎn)換。

常量強(qiáng)制(Const Cast):使用 const_cast 去除常量屬性,用于修改對(duì)象的 const 或 volatile 屬性。

示例代碼如下所示:int main() {

float f = 3.14;

int num1 = static_cast(f); // 靜態(tài)強(qiáng)制轉(zhuǎn)換

int* ptr1 = reinterpret_cast(&f); // 重新解釋強(qiáng)制轉(zhuǎn)換

const char* str = "Hello";

char* nonConstStr = const_cast(str); // 常量強(qiáng)制轉(zhuǎn)換

return 0;

}

通過(guò)顯式類型轉(zhuǎn)換,我們可以控制類型之間的轉(zhuǎn)換,并確保在需要時(shí)進(jìn)行正確且明確的類型轉(zhuǎn)換操作。

36、什么是智能指針(Smart Pointer)?請(qǐng)列舉幾種智能指針,并解釋它們的使用情境。

智能指針(Smart Pointer)是C++中的一種RAII(資源獲取即初始化)對(duì)象,用于管理動(dòng)態(tài)分配的內(nèi)存資源。它們提供了自動(dòng)化的內(nèi)存管理和安全釋放,減少了手動(dòng)內(nèi)存管理錯(cuò)誤的可能性。

以下是幾種常見(jiàn)的智能指針及其使用情境:std::unique_ptr: std::unique_ptr 是獨(dú)占所有權(quán)的智能指針,它確保只有一個(gè)指針可以訪問(wèn)所管理的資源。當(dāng)需要在多個(gè)地方共享資源時(shí),應(yīng)該選擇其他智能指針。使用 new 運(yùn)算符創(chuàng)建對(duì)象并將其包裝在 std::unique_ptr 中。

示例:std::unique_ptr ptr(new int(42));

std::shared_ptr: std::shared_ptr 是共享所有權(quán)的智能指針,它允許多個(gè)指針共同擁有和訪問(wèn)所管理的資源,并使用引用計(jì)數(shù)來(lái)跟蹤資源被引用的次數(shù)。當(dāng)需要在多個(gè)地方共享資源且不關(guān)心所有者身份時(shí),應(yīng)該選擇 std::shared_ptr。

示例:std::shared_ptrptr1 = std::make_shared(42);

std::shared_ptrptr2 = ptr1;

std::weak_ptr: std::weak_ptr 也是一種共享所有權(quán)的智能指針,但不增加引用計(jì)數(shù)。它允許觀察資源的狀態(tài)而不擁有資源本身,避免了循環(huán)引用問(wèn)題,并可以檢測(cè)資源是否被釋放。

示例:std::shared_ptrsharedPtr = std::make_shared(42);

std::weak_ptrweakPtr(sharedPtr);

if (auto lockedPtr = weakPtr.lock()) {

// 訪問(wèn) lockedPtr 所指向的資源

} else {

// 資源已被釋放

}

智能指針通過(guò)其析構(gòu)函數(shù)自動(dòng)釋放所管理的資源,無(wú)需手動(dòng)調(diào)用 delete 或 free。它們提供了方便、安全和高效的內(nèi)存管理機(jī)制,幫助減少內(nèi)存泄漏和懸掛指針等問(wèn)題的發(fā)生。使用智能指針可以簡(jiǎn)化代碼并提高程序可靠性。

37、C++11引入了哪些新特性和語(yǔ)法改進(jìn)?例如,lambda表達(dá)式、auto關(guān)鍵字等。

Lambda 表達(dá)式:允許在代碼中定義匿名函數(shù),可以方便地編寫(xiě)簡(jiǎn)短、內(nèi)聯(lián)的函數(shù)對(duì)象。

auto 關(guān)鍵字:用于自動(dòng)推斷變量的類型。通過(guò)使用 auto,編譯器可以根據(jù)變量的初始值來(lái)推斷其類型。

Range-based for 循環(huán):提供了一種更簡(jiǎn)潔、直觀的遍歷容器元素的方式。

nullptr 關(guān)鍵字:表示空指針,替代了傳統(tǒng)的 NULL 宏定義,具有更明確和安全的語(yǔ)義。

強(qiáng)類型枚舉(Scoped Enum):引入了具有作用域限定符和強(qiáng)類型的枚舉類型,解決了傳統(tǒng)枚舉帶來(lái)的一些問(wèn)題。

智能指針(Smart Pointer):包括 std::unique_ptr、std::shared_ptr 和 std::weak_ptr,提供了更安全和方便地管理動(dòng)態(tài)內(nèi)存分配的機(jī)制。

移動(dòng)語(yǔ)義(Move Semantics)和右值引用(Rvalue References):通過(guò) std::move 和 && 語(yǔ)法支持高效地轉(zhuǎn)移資源所有權(quán),避免不必要的復(fù)制操作。

初始化列表(Initializer Lists):可以在對(duì)象構(gòu)造時(shí)使用花括號(hào)初始化列表進(jìn)行初始化操作。

靜態(tài)斷言(Static Assert):用于在編譯時(shí)進(jìn)行靜態(tài)條件檢查,如果條件不滿足,則導(dǎo)致編譯錯(cuò)誤。

并發(fā)支持庫(kù)(Concurrency Support Library):包括 std::thread、std::mutex、std::condition_variable 等,提供了線程和并發(fā)操作的標(biāo)準(zhǔn)庫(kù)支持。

38、解釋C++中的靜態(tài)斷言(Static Assertion)和動(dòng)態(tài)斷言(Dynamic Assertion)之間的區(qū)別。

在C++中,靜態(tài)斷言(Static Assertion)和動(dòng)態(tài)斷言(Dynamic Assertion)都是用于在程序中進(jìn)行條件檢查的機(jī)制,但它們有一些重要的區(qū)別。

靜態(tài)斷言(Static Assertion):

靜態(tài)斷言是在編譯時(shí)進(jìn)行的,即在代碼被編譯之前就會(huì)執(zhí)行。

使用靜態(tài)斷言可以對(duì)編譯期間已知的條件進(jìn)行檢查。

靜態(tài)斷言使用靜態(tài)表達(dá)式來(lái)定義條件,并且如果條件為假,則會(huì)導(dǎo)致編譯錯(cuò)誤。

靜態(tài)斷言通常用于驗(yàn)證編譯期常量、類型屬性或其他與類型相關(guān)的約束。

動(dòng)態(tài)斷言(Dynamic Assertion):

動(dòng)態(tài)斷言是在運(yùn)行時(shí)進(jìn)行的,即在程序執(zhí)行過(guò)程中才會(huì)執(zhí)行。

使用動(dòng)態(tài)斷言可以對(duì)運(yùn)行時(shí)條件進(jìn)行檢查。

動(dòng)態(tài)斷言使用 assert() 宏來(lái)定義條件,并且如果條件為假,則會(huì)觸發(fā)一個(gè)運(yùn)行時(shí)錯(cuò)誤,并終止程序執(zhí)行。

動(dòng)態(tài)斷言通常用于驗(yàn)證假設(shè)、調(diào)試程序或捕獲意外情況。

39、請(qǐng)解釋C++中的析構(gòu)函數(shù)可以是虛函數(shù),而構(gòu)造函數(shù)不能。

在C++中,析構(gòu)函數(shù)可以被聲明為虛函數(shù),而構(gòu)造函數(shù)不能。這是因?yàn)樘摵瘮?shù)的概念和對(duì)象的生命周期有關(guān)。

析構(gòu)函數(shù):

析構(gòu)函數(shù)用于釋放對(duì)象所占用的資源,并執(zhí)行其他必要的清理操作。

當(dāng)一個(gè)對(duì)象被銷毀時(shí)(如離開(kāi)作用域、delete操作),它的析構(gòu)函數(shù)會(huì)被自動(dòng)調(diào)用。

如果一個(gè)類需要在繼承體系中進(jìn)行多態(tài)使用,即通過(guò)基類指針或引用來(lái)訪問(wèn)派生類對(duì)象,那么基類的析構(gòu)函數(shù)應(yīng)當(dāng)聲明為虛函數(shù)。

聲明為虛函數(shù)可以確保當(dāng)基類指針指向派生類對(duì)象并刪除該指針時(shí),會(huì)正確調(diào)用派生類的析構(gòu)函數(shù),從而避免內(nèi)存泄漏。

構(gòu)造函數(shù):

構(gòu)造函數(shù)負(fù)責(zé)初始化對(duì)象,并在創(chuàng)建對(duì)象時(shí)被自動(dòng)調(diào)用。

構(gòu)造過(guò)程中對(duì)象還沒(méi)有完全形成,并且無(wú)法確定其實(shí)際類型(因?yàn)樗€沒(méi)有被完全創(chuàng)建)。

在構(gòu)造階段,如果將構(gòu)造函數(shù)聲明為虛擬,則無(wú)法實(shí)現(xiàn)多態(tài)行為,因?yàn)檎{(diào)用虛擬機(jī)制需要已經(jīng)創(chuàng)建了完整的對(duì)象。同時(shí),在調(diào)用虛擬方法之前也無(wú)法確定其實(shí)際類型。

40、const與#define的區(qū)別

作用域不同:

const:const關(guān)鍵字定義的常量具有塊級(jí)作用域,在定義的作用域內(nèi)有效。

#define:宏定義的常量沒(méi)有作用域限制,它是全局有效的。

類型檢查不同:

const:const關(guān)鍵字定義的常量是有類型的,并且在編譯時(shí)進(jìn)行類型檢查。它會(huì)對(duì)變量賦予一個(gè)只讀屬性,不能再被修改。

#define:#define是預(yù)處理指令,在預(yù)處理階段進(jìn)行簡(jiǎn)單文本替換。沒(méi)有類型信息或類型檢查,只是將標(biāo)識(shí)符替換為相應(yīng)的文本。

內(nèi)存占用不同:

const:每個(gè)使用const聲明的變量都會(huì)在內(nèi)存中分配存儲(chǔ)空間。

#define:宏定義只是簡(jiǎn)單地進(jìn)行文本替換,沒(méi)有額外的內(nèi)存開(kāi)銷。

可讀性和調(diào)試性不同:

const:使用const可以提供更好的可讀性,因?yàn)槌A棵Q具有明確含義,并且可以進(jìn)行類型推斷。也可以通過(guò)調(diào)試器進(jìn)行調(diào)試。

#define:由于只是簡(jiǎn)單替換文本,可能導(dǎo)致代碼難以理解和調(diào)試。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多