中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站及網(wǎng)頁設(shè)計費用市場營銷策劃公司排名

網(wǎng)站及網(wǎng)頁設(shè)計費用,市場營銷策劃公司排名,制作網(wǎng)頁需要學(xué)什么語言,政府網(wǎng)站誰做的1.1QT介紹 1.1.1 QT簡介 Qt 是一個跨平臺的應(yīng)用程序和用戶界面框架,用于開發(fā)圖形用戶界面(GUI)應(yīng)用程序以及命令行工具。它最初由挪威的 Trolltech (奇趣科技)公司開發(fā),現(xiàn)在由 Qt Company 維護(hù)&#xff…

1.1QT介紹

1.1.1 QT簡介

Qt 是一個跨平臺的應(yīng)用程序和用戶界面框架,用于開發(fā)圖形用戶界面(GUI應(yīng)用程序以及命令行工具。它最初由挪威的 Trolltech (奇趣科技)公司開發(fā),現(xiàn)在由 Qt Company 維護(hù),2020128日發(fā)布QT6。Qt 使用 C++ 語言編寫,支持多種編程語言通過綁定進(jìn)行使用。

1.1.2?QT Creator 常用的快捷鍵使用基本介紹

2.1 命名空間

2.1.1命名空間作用

創(chuàng)建自己的命名空間是 C++ 中組織代碼的一種好方法,特別是在開發(fā)大型項目或庫時。命名空間可以幫助你避免名稱沖突,并且清晰地組織代碼。

std C++ 標(biāo)準(zhǔn)庫的命名空間。它是一個定義在 C++ 標(biāo)準(zhǔn)庫中的所有類、函數(shù)和變量的命名空間。

C++ 中,如果你想使用標(biāo)準(zhǔn)庫中的任何類、函數(shù)或?qū)ο?#xff0c;你通常有兩種選擇:

1. 使用 std:: 前綴:這是最常見的方式,它明確指定了你正在使用的是位于 std 命名空間中的元

素。

std::cout << "Hello, world!" << std::endl;

2. 使用 using namespace std; :這允許你在不顯式指定 std:: 的情況下使用 std 命名空間中的

所有元素。

using namespace std;

cout << "Hello, world!" << endl;

std包含的內(nèi)容

std 命名空間包含了許多類、函數(shù)和對象,例如:

輸入輸出庫(如 std::cout , std::cin , std::endl

容器類(如 std::vector , std::map , std::set

字符串類( std::string

異常類( std::exception 和相關(guān)子類)

算法(如 std::sort , std::find

實用工具(如 std::pair , std::tuple

其他許多功能

使用建議

對于小型代碼或示例代碼,使用 using namespace std; 通常是安全的。

對于大型項目或庫,建議顯式地使用 std:: 前綴,以避免潛在的名稱沖突,并提高代碼的可讀性

和可維護(hù)性。

std 命名空間是 C++ 編程的基礎(chǔ)部分,理解和正確使用它對于編寫健壯和高效的 C++ 代碼至關(guān)重要。

2.1.2自定義命名空間

定義命名空間

假設(shè)我們要創(chuàng)建一個命名空間來包含與圓形相關(guān)的功能。我們可以命名這個命名空間為 cir

在這個頭文件中,我們定義了一個名為 cir 的命名空間,其中包含了計算圓的面積和周長的函數(shù),以及圓周率常量 PI 。

使用命名空間

在另一個文件中,我們可以使用這個命名空間中定義的函數(shù)和常量:

main.cpp 中,我們首先包含了定義 Cir 命名空間的頭文件。然后,我們可以使用 Cir:: 前綴來訪 問該命名空間中的函數(shù)和常量。

通過使用自定義命名空間,你可以有效地組織你的代碼,并減少不同庫之間的名稱沖突。這在大型項目和團(tuán)隊協(xié)作中尤其重要。

輸出結(jié)果

2.2 C語言快速入門

2.2.1 輸入輸出

C++ 中的輸入和輸出(I/O)主要是通過標(biāo)準(zhǔn)庫中的輸入輸出流來實現(xiàn)的。最常用的是 iostream 庫,它提供了用于輸入和輸出的基本流類,包括 cin 、 cout 、 cerr clog

標(biāo)準(zhǔn)輸出流 ( cout )

cout 代表標(biāo)準(zhǔn)輸出流,通常用于向屏幕輸出數(shù)據(jù)。

使用操作符 << (插入操作符)向 cout 發(fā)送數(shù)據(jù)。

例如, std::cout << "Hello, world!" << std::endl; 會在屏幕上打印 "Hello, world!" 并換行。

標(biāo)準(zhǔn)輸入流 ( cin )

cin 代表標(biāo)準(zhǔn)輸入流,用于從鍵盤接收數(shù)據(jù)。

使用操作符 >> (提取操作符)從 cin 提取數(shù)據(jù)。

例如, int x; std::cin >> x; 會從用戶那里讀取一個整數(shù)并存儲在變量 x 中。

標(biāo)準(zhǔn)錯誤流 ( cerr ) 和標(biāo)準(zhǔn)日志流 ( clog )

cerr 用于輸出錯誤消息。與 cout 不同, cerr 不是緩沖的,這意味著它會立即輸出。

clog 類似于 cerr ,但它是緩沖的。它通常用于記錄錯誤和日志信息。

2.2.2 基本變量類型

C++ 基本數(shù)據(jù)類型整理成表格。以下是一個表格,展示了不同的基本數(shù)據(jù)類型及其一般用途和大小范圍:

C語言類似。

2.2.3?內(nèi)聯(lián)函數(shù)

內(nèi)聯(lián)函數(shù)(Inline Function)是C++中一種特殊的函數(shù),其定義直接在每個調(diào)用點展開。這意味著編譯器會嘗試將函數(shù)調(diào)用替換為函數(shù)本身的代碼,這樣可以減少函數(shù)調(diào)用的開銷,尤其是在小型函數(shù)中。

特點

1. 減少函數(shù)調(diào)用開銷:內(nèi)聯(lián)函數(shù)通常用于優(yōu)化小型、頻繁調(diào)用的函數(shù),因為它避免了函數(shù)調(diào)用的常規(guī)開銷(如參數(shù)傳遞、棧操作等)。

2. 編譯器決策:即使函數(shù)被聲明為內(nèi)聯(lián),編譯器也可能決定不進(jìn)行內(nèi)聯(lián),特別是對于復(fù)雜或遞歸函 數(shù)。

3. 適用于小型函數(shù):通常只有簡單的、執(zhí)行時間短的函數(shù)適合做內(nèi)聯(lián)

4. 定義在每個使用點:內(nèi)聯(lián)函數(shù)的定義(而非僅僅是聲明)必須對每個使用它的文件都可見,通常意味著將內(nèi)聯(lián)函數(shù)定義在頭文件中。

使用方法

通過在函數(shù)聲明前添加關(guān)鍵字 inline 來指示編譯器該函數(shù)適合內(nèi)聯(lián):

inline int max(int x, int y)

{

????????return x > y ? x : y;

}

示例

#include <iostream>

inline int add(int a, int b)

{

????????return a + b;

}

int main()

{

????????int result = add(5, 3); // 編譯器可能會將此替換為:int result = 5 + 3;

????????std::cout << "Result: " << result << std::endl;

????????return 0;

}

在這個示例中,函數(shù) add 被定義為內(nèi)聯(lián)函數(shù)。當(dāng)它被調(diào)用時,編譯器可能會將函數(shù)調(diào)用替換為函數(shù)體內(nèi)的代碼。

注意事項

過度使用的風(fēng)險:不應(yīng)濫用內(nèi)聯(lián)函數(shù),因為這可能會增加最終程序的大小(代碼膨脹)。對于大型

函數(shù)或遞歸函數(shù),內(nèi)聯(lián)可能導(dǎo)致性能下降。

編譯器的決定:最終是否將函數(shù)內(nèi)聯(lián)是由編譯器決定的,即使函數(shù)被標(biāo)記為 inline

適用場景:最適合內(nèi)聯(lián)的是小型函數(shù)和在性能要求高的代碼中頻繁調(diào)用的函數(shù)。

內(nèi)聯(lián)函數(shù)是一種用于優(yōu)化程序性能的工具,但需要合理使用,以確保代碼的可維護(hù)性和性能的平衡。

2.2.4?Lambda 表達(dá)式

Lambda 表達(dá)式是 C++11 引入的一種匿名函數(shù)的方式,它允許你在需要函數(shù)的地方內(nèi)聯(lián)地定義函數(shù),而無需單獨命名函數(shù)

Lambda 表達(dá)式的基本語法如下:

[capture clause](parameters) -> return_type

{

????????// 函數(shù)體

????????// 可以使用捕獲列表中的變量

????????return expression; // 可選的返回語句

}

Lambda 表達(dá)式由以下部分組成:

捕獲列表(Capture clause:用于捕獲外部變量,在 Lambda 表達(dá)式中可以訪問這些變量。捕

獲列表可以為空,也可以包含變量列表 [var1, var2, ...] 。

參數(shù)列表(Parameters:與普通函數(shù)的參數(shù)列表類似,可以為空或包含參數(shù)列表 (param1,

param2, ...) 。

返回類型(Return typeLambda 表達(dá)式可以自動推斷返回類型auto,也可以顯式指定返回類

-> return_type 。如果函數(shù)體只有一條返回語句,可以省略返回類型。

函數(shù)體(BodyLambda 表達(dá)式的函數(shù)體,包含需要執(zhí)行的代碼。


Lambda 表達(dá)式最簡單的案例是在需要一個小型函數(shù)或臨時函數(shù)時直接使用它。以下是一個非常簡單的例子,其中使用 Lambda 表達(dá)式來定義一個加法操作,并立即使用它來計算兩個數(shù)的和。

#include <iostream>

int main()

{

????????// 定義一個簡單的 Lambda 表達(dá)式進(jìn)行加法

????????auto add = [ ](int a, int b)

????????{

????????????????return a + b;

????????};

????????// 使用 Lambda 表達(dá)式計算兩個數(shù)的和

????????int sum = add(10, 20);

????????std::cout << "Sum is: " << sum << std::endl;

????????return 0;

}

在這個例子中:

我們定義了一個名為 add Lambda 表達(dá)式,它接受兩個整數(shù)參數(shù),并返回它們的和。然后,我們使用這個 Lambda 表達(dá)式來計算兩個數(shù)字(10 20)的和,并將結(jié)果存儲在變量 sum中。最后,我們打印出這個和。

這個例子展示了 Lambda 表達(dá)式的基本用法:作為一種簡潔而快速的方式來定義小型函數(shù)。


我們可以寫一個例子,其中使用一個函數(shù)來找出兩個數(shù)中的較大數(shù),這個函數(shù)將接受一個 lambda 函數(shù)作為回調(diào)來比較這兩個數(shù)。Lambda 函數(shù)將直接在函數(shù)調(diào)用時定義,完全是匿名的。

先回憶以下回調(diào)函數(shù)

#include <iostream>

bool myCompare(int a, int b)

{

????????return a > b;

}

int getMax(?int a, int b, bool?(*compare)(int, int) )

{

????????if (compare(a, b))

???????? {

????????????????return a;

????????} else

????????{

????????????????return b;

????????}

}

int main()

{

????????int x = 10;

????????int y = 20;

????????// 回調(diào)函數(shù)

????????int max = getMax(x, y, myCompare);

????????std::cout << "The larger number is: " << max << std::endl;

????????return 0;

}

示例:使用匿名 Lambda 函數(shù)來返回兩個數(shù)中的較大數(shù)

#include <iostream>

// 函數(shù),接受兩個整數(shù)和一個比較的 lambda 函數(shù)

int getMax(int a, int b, bool(*compare)(int, int))

{

????????if (compare(a, b))

????????{

????????????????return a;

????????} else

???????? {

????????????????return b;

????????}

}

int main()

{

????????int x = 10;

????????int y = 20;

????????// 直接在函數(shù)調(diào)用中定義匿名 lambda 函數(shù)

????????int max = getMax(x, y, [ ](int a, int b) -> bool

????????{

????????????????return a > b;

????????});

????????std::cout << "The larger number is: " << max << std::endl;

????????return 0;

}

在這個例子中:

getMax 函數(shù)接受兩個整數(shù) a b ,以及一個比較函數(shù) compare 。這個比較函數(shù)是一個指向函數(shù) 的指針,它接受兩個整數(shù)并返回一個布爾值。在 main 函數(shù)中,我們調(diào)用 getMax ,并直接在調(diào)用點定義了一個匿名的 lambda 函數(shù)。這個lambda 函數(shù)接受兩個整數(shù)并返回一個表示第一個整數(shù)是否大于第二個整數(shù)的布爾值。這個 lambda 函數(shù)在 getMax 中被用作比較兩個數(shù)的邏輯。根據(jù) lambda 函數(shù)的返回值, getMax返回較大的數(shù)。

這個例子展示了如何直接在函數(shù)調(diào)用中使用匿名 lambda 函數(shù),使代碼更加簡潔和直接。這種方法在需要臨時函數(shù)邏輯的場合非常有用,尤其是在比較、條件檢查或小型回調(diào)中。


Lambda 表達(dá)式中,參數(shù)捕獲是指 Lambda 表達(dá)式從其定義的上下文中捕獲變量的能力。這使得Lambda 可以使用并操作在其外部定義的變量。捕獲可以按值(拷貝)或按引用進(jìn)行。

讓我們通過一個簡單的示例來展示帶參數(shù)捕獲的 Lambda 表達(dá)式。

輸出

在這個例子中:

第一個 Lambda 表達(dá)式 sum 按值捕獲了 x y (即它們的副本)。這意味著 sum 內(nèi)的 x y

是在 Lambda 定義時的值的拷貝。

第二個 Lambda 表達(dá)式 mul?使用 [=] 捕獲列表,這表示它按值捕獲所有外部變量。

第三個 Lambda 表達(dá)式 modify_mul?使用 [&] 捕獲列表,這表示它按引用捕獲所有外部變量。因此,它可以修改 x y 的原始值。

這個示例展示了如何使用不同類型的捕獲列表(按值和按引用)來控制 Lambda 表達(dá)式對外部變量的訪問和修改。按值捕獲是安全的,但不允許修改原始變量,而按引用捕獲允許修改原始變量,但需要注意引用的有效性和生命周期問題。

以下是一個表格,概述了 Lambda 函數(shù)和內(nèi)聯(lián)函數(shù)在 C++ 中的相似之處和區(qū)別:

請注意,雖然 Lambda 函數(shù)和內(nèi)聯(lián)函數(shù)在某些方面有相似之處,如它們都可以被編譯器優(yōu)化以減少調(diào)用開銷,但它們在設(shè)計和用途上有明顯的不同。Lambda 函數(shù)的核心優(yōu)勢在于它們的匿名性和對外部變量的捕獲能力,而內(nèi)聯(lián)函數(shù)則主要關(guān)注于提高小型函數(shù)的性能。

2.3類

2.3.1 類的初探

C++ 中的類(class)是一種編程結(jié)構(gòu),用于創(chuàng)建對象。這些對象可以擁有屬性(即數(shù)據(jù)成員)和行為(即成員函數(shù)或方法)。類的概念是面向?qū)ο缶幊痰暮诵闹?#xff0c;其主要目的是將數(shù)據(jù)和與數(shù)據(jù)相關(guān)的操封裝在一起。例如,如果你有一個汽車類,它可能包含顏色、品牌、型號等屬性(數(shù)據(jù)成員),以及啟動、停止、加速等行為(成員函數(shù))。每當(dāng)你基于這個類創(chuàng)建一個對象時,你就有了一個具體的汽車,具有這些屬性和行為。

C++ 類的基本結(jié)構(gòu)通常包含:

1. 數(shù)據(jù)成員(Attributes:定義類的屬性。這些是類內(nèi)部的變量,用于存儲對象的狀態(tài)。

2. 成員函數(shù)(Methods:定義類的行為。這些是可以操作對象的數(shù)據(jù)成員的函數(shù)。

3. 構(gòu)造函數(shù)和析構(gòu)函數(shù):特殊的成員函數(shù)。構(gòu)造函數(shù)在創(chuàng)建對象時自動調(diào)用,用于初始化對象。析構(gòu)函數(shù)在對象銷毀時調(diào)用,用于執(zhí)行清理操作。

4. 訪問修飾符:如 public , private , protected ,用于控制對類成員的訪問權(quán)限。例如, public成員可以在類的外部訪問,而 private 成員只能在類內(nèi)部訪問。

5. 繼承:允許一個類繼承另一個類的特性。這是代碼重用和多態(tài)性的關(guān)鍵。

通過這些特性,C++ 類提供了一種強(qiáng)大的方式來組織和處理數(shù)據(jù),使得代碼更加模塊化、易于理解和維護(hù)。

2.3.2 結(jié)構(gòu)體引入類

2.3.2.1 回憶結(jié)構(gòu)體

如果用C語言實現(xiàn)上面描述的汽車類,我們實現(xiàn)如下代碼

輸出

2.3.2.2 新建C++工程來使用結(jié)構(gòu)體

C++中,字符串用string來表示,發(fā)現(xiàn)有個string賦值給char 的警告,所以修改所有char *為 string類型

main . cpp : 33 : 17 : warning : ISO C ++ 11 does not allow conversion from string literal
to 'char *'

修改后,發(fā)現(xiàn)printf%s控制位,不能用于string的輸出,所有有string構(gòu)建了即將要輸出的字符串

C++中,通過std::tostring()函數(shù),將整型數(shù)轉(zhuǎn)化成字符串

printCarInfo中使用cout輸出汽車信息

發(fā)現(xiàn)在C++工程中,使用malloc在堆申請結(jié)構(gòu)體空間有問題,所以直接在此引入類的概念,把struct改成class

引入新問題,class的成員數(shù)據(jù)和成員函數(shù)在不指定權(quán)限的情況下,默認(rèn)private權(quán)限,類的對象無法進(jìn)行直接訪問

main.cpp:33:9: error: 'color' is a private member of 'Car'

main.cpp:5:11: note: implicitly declared private here

添加public屬性

main函數(shù)中的原本結(jié)構(gòu)體變量改成了類的實例化,如果變量類型是指針,把原來的malloc改成

new一個對象

最后解決了所有問題

但是!我們還沒有真正體驗到面向?qū)ο蟮姆庋b特性,僅僅感受到權(quán)限上的區(qū)別

2.3.2.3 真正的成員函數(shù)

上一節(jié)的案例中, void (*printCarInfo)(string color,string brand,string type, int year); 到底是變量函數(shù)還是成員函數(shù)呢?

答:是一個指針變量,是保存某個函數(shù)地址的變量,所以它不是成員函數(shù),是成員數(shù)據(jù)

真正的成員函數(shù)遵守封裝特性,在函數(shù)體內(nèi)部訪問成員數(shù)據(jù)的時候,不需要參數(shù)傳遞

C++ 中,雙冒號 :: 稱為 "作用域解析運(yùn)算符"Scope Resolution Operator)。它用于指定一

個成員(如函數(shù)或變量)屬于特定的類或命名空間。例如,在類的外部定義成員函數(shù)時, :: 用于

指明該函數(shù)屬于哪個類。

2.3.4 QT中經(jīng)常出現(xiàn)的用法

在 C++中,一個類包含另一個類的對象稱為組合(Composition)。這是一種常見的設(shè)計模式,用

于表示一個類是由另一個類的對象組成的。這種關(guān)系通常表示一種"擁有"("has-a")的關(guān)系。

普通變量訪問成員變量或者成員函數(shù),使用 “ . ” 運(yùn)算符

指針變量訪問成員變量或者成員函數(shù),使用“ -> ”運(yùn)算符,像C語言的結(jié)構(gòu)體用法

輸出

2.4 權(quán)限初識

2.4.1 基本介紹

C++中的訪問權(quán)限主要分為三種: public private protected 。這些權(quán)限決定了類成員(包括數(shù)據(jù)成員和成員函數(shù))的可訪問性。以下是一個總結(jié)表格,說明了在不同情況下這些權(quán)限如何應(yīng)用:

使用權(quán)限(如 public 、 private protected )在C++中是一種關(guān)鍵的封裝手段,它們旨在控制對類成員的訪問。下面是一個表格,總結(jié)了使用權(quán)限的主要好處和潛在缺點:

2.4.2 目前能概況的結(jié)論

public 權(quán)限相當(dāng)于我們學(xué)習(xí)C語言結(jié)構(gòu)體一樣,不考慮訪問權(quán)限的存在,但是要注意,類中不寫權(quán)

限,默認(rèn)是私有權(quán)限

protected 留到繼承講解的時候再提

private 私有權(quán)限,通過一下案例向各位表達(dá)一下作用的意思,但需要未來實戰(zhàn)中慢慢體會。

這個例子將闡述在類設(shè)計中使用 private 成員的必要性。我們將創(chuàng)建一個簡單的 BankAccount 類,展示如何使用 private 來保護(hù)賬戶的余額,確保它只能通過指定的方法進(jìn)行修改。

所以,我們可以腦部一個場景:

銀行的賬戶是一個模板,是一個類,有存款人信息和賬戶額度,而具體的存款人視為一個對象,一個對象不能私自修改賬戶額度,需要通過一個操作流程,比如去ATM或者柜臺進(jìn)行操作才能修改到賬戶額度,所以,存款人信息和賬戶額度設(shè)計成私有權(quán)限,通過公有的操作流程,也就是公有函數(shù)去操作私有變量。

基于這個場景,我們編程實現(xiàn)代碼

輸出

在這個示例中, balance 是一個 private 成員變量,它不能被類的外部直接訪問。這保證了賬戶余額只能通過類提供的方法(如 putinMoney?, getfromMoney, getBalance )來修改和查詢,從而防止了不合適的修改,比如直接設(shè)置余額為負(fù)數(shù)或任意值。這樣的設(shè)計保證了類的封裝性和數(shù)據(jù)的完整性。

2.4.3 提問和回答

問:為什么新手學(xué)習(xí)C++感受不到訪問權(quán)限的必要性呢?

答:新手學(xué)習(xí)C++時可能不會立即感受到訪問權(quán)限(如 public 、 private 、 protected )的必要性,主要有以下幾個原因:

1. 簡單的例子和練習(xí):初學(xué)者通常從簡單的例子和練習(xí)開始,這些例子可能不需要復(fù)雜的封裝或繼承結(jié)構(gòu)。在這種情況下,訪問權(quán)限的作用可能不太明顯。

2. 封裝的概念需要時間去理解:封裝是面向?qū)ο缶幊讨械囊粋€核心概念,但對于初學(xué)者來說,理解封裝的價值需要一定的時間和實踐。在初期,更多的關(guān)注點可能放在基本語法和程序結(jié)構(gòu)上。

3. 缺乏大型項目經(jīng)驗:在小型項目或單文件程序中,訪問權(quán)限的重要性可能不如在大型、多人協(xié)作的項目中那么顯著。在復(fù)雜的軟件開發(fā)中,適當(dāng)?shù)脑L問控制對于代碼的維護(hù)性和可讀性至關(guān)重要。

4. 直接操作感覺更簡單:對于初學(xué)者來說,直接訪問和修改類的所有成員可能看起來更簡單直接。他們可能還沒有遇到由于不恰當(dāng)訪問控制導(dǎo)致的維護(hù)和調(diào)試問題。

5. 抽象和設(shè)計模式的理解:理解何時以及如何使用訪問權(quán)限通常涉及到對軟件設(shè)計模式和抽象的深入理解。這些通常是隨著經(jīng)驗積累和更深入的學(xué)習(xí)而逐漸掌握的。

隨著經(jīng)驗的增長,學(xué)習(xí)者開始處理更復(fù)雜的項目,他們將開始意識到恰當(dāng)?shù)脑L問控制的重要性,特別是在保持代碼的可維護(hù)性、可讀性以及在團(tuán)隊環(huán)境中的協(xié)作方面。因此,對于教育者和學(xué)習(xí)者來說,強(qiáng)調(diào)并實踐這些概念是很重要的,以便在編程技能成熟時能夠有效地運(yùn)用它們。

2.5 引用

引用變量是一個別名,也就是說,它是某個已存在變量的另一個名字。

一旦把引用初始化為某個變量,就可以使用該引用名稱或變量名稱來指向變量。

思維發(fā)散:

C語言中,一個數(shù)據(jù)對應(yīng)一個內(nèi)存,通過由一個變量名來訪問這個內(nèi)存空間的數(shù)據(jù),叫做直接訪問,相對直接訪問,有個間接訪問的說法,叫做指針。

而引用相當(dāng)于又給這個內(nèi)存中的數(shù)據(jù)提供了一個新的變量名,

這個變量名功能比傳統(tǒng)變量名更特殊,是直達(dá)地址的,后續(xù)代碼驗證!

2.5.1 和指針的區(qū)別

引用很容易與指針混淆,它們之間有三個主要的不同:

1.不存在空引用。引用必須連接到一塊合法的內(nèi)存。

2.一旦引用被初始化為一個對象,就不能被指向到另一個對象。指針可以在任何時候指向到另一個對象。

3.引用必須在創(chuàng)建時被初始化。指針可以在任何時間被初始化。

官方?jīng)]有明確說明,但是引用確實不是傳統(tǒng)意義上的獨立變量,它不能

試想變量名稱是變量附屬在內(nèi)存位置中的標(biāo)簽,可以把引用當(dāng)成是變量附屬在內(nèi)存位置中的第二

個標(biāo)簽。因此,可以通過原始變量名稱或引用來訪問變量的內(nèi)容。例如:

int i = 17 ; int* p = & i ; * p = 20 ;

我們可以為 i 聲明引用變量,如下所示:

int& r = i;

double& s = d;

在這些聲明中,& 讀作引用。

因此,第一個聲明可以讀作 "r 是一個初始化為 i 的整型引用",第二個聲明可以讀作 "s 是一個初始化為 d double 型引用"。

下面的實例使用了 int double 引用:

輸出

2.5.2 把引用作為參數(shù)

我們已經(jīng)討論了如何使用指針來實現(xiàn)引用調(diào)用函數(shù)。下面的實例使用了引用來實現(xiàn)引用調(diào)用函數(shù)。

輸出

2.5.3 把引用作為返回值

通過使用引用來替代指針,會使 C++ 程序更容易閱讀和維護(hù)。C++ 函數(shù)可以返回一個引用,方式與返回一個指針類似。

當(dāng)函數(shù)返回一個引用時,則返回一個指向返回值的隱式指針。

這樣,函數(shù)就可以放在賦值語句的左邊。

例如,請看下面這個簡單的程序:

輸出

2.6 重載

2.6.1 函數(shù)重載

在同一個作用域內(nèi),可以聲明幾個功能類似的同名函數(shù),這些同名函數(shù)的形式參數(shù)(指參數(shù)的個數(shù)、類型或者順序)必須不同。不能僅通過返回類型的不同來重載函數(shù)。

下面的實例中,同名函數(shù) print() 被用于輸出不同的數(shù)據(jù)類型:

輸出

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

2.7.1 什么是構(gòu)造函數(shù)

類的構(gòu)造函數(shù)是類的一種特殊的成員函數(shù),它會在每次創(chuàng)建類的新對象時執(zhí)行。

構(gòu)造,那構(gòu)造的是什么呢?

構(gòu)造成員變量的初始化值,內(nèi)存空間等

構(gòu)造函數(shù)的名稱與類的名稱是完全相同的,并且不會返回任何類型,也不會返回 void。構(gòu)造函數(shù)可用于為某些成員變量設(shè)置初始值。

2.7.2 帶參數(shù)構(gòu)造函數(shù)

默認(rèn)的構(gòu)造函數(shù)沒有任何參數(shù),但如果需要,構(gòu)造函數(shù)也可以帶有參數(shù)。這樣在創(chuàng)建對象時就會給對象賦初始值

下面的實例有助于更好地理解構(gòu)造函數(shù)的概念:

輸出

2.7.3?使用初始化列表

C++中,使用初始化列表來初始化類的字段是一種高效的初始化方式,尤其在構(gòu)造函數(shù)中。初始化列表直接在對象的構(gòu)造過程中初始化成員變量,而不是先創(chuàng)建成員變量后再賦值。這對于提高性能尤其重要,特別是在涉及到復(fù)雜對象或引用和常量成員的情況下。

初始化列表緊跟在構(gòu)造函數(shù)參數(shù)列表后面,以冒號( : )開始,后跟一個或多個初始化表達(dá)式,每個表達(dá)式通常用逗號分隔。下面是使用初始化列表初始化字段的例子:

輸出

初始化列表的優(yōu)點包括:

1. 效率:對于非基本類型的對象,使用初始化列表比在構(gòu)造函數(shù)體內(nèi)賦值更高效,因為它避免了先默認(rèn)構(gòu)造然后再賦值的額外開銷。

2. 必要性:對于引用類型和常量類型的成員變量,必須使用初始化列表,因為這些類型的成員變量在構(gòu)造函數(shù)體內(nèi)不能被賦值。

3. 順序:成員變量的初始化順序是按照它們在類中聲明的順序,而不是初始化列表中的順序。

使用初始化列表是C++中推薦的初始化類成員變量的方式,因為它提供了更好的性能和靈活性。

2.7.4?this關(guān)鍵字

C++ 中, this 關(guān)鍵字是一個指向調(diào)用對象的指針。它在成員函數(shù)內(nèi)部使用,用于引用調(diào)用該函數(shù)的對象。使用 this 可以明確指出成員函數(shù)正在操作的是哪個對象的數(shù)據(jù)成員。

示例代碼

下面的代碼展示了如何使用 this 關(guān)鍵字:

輸出

在這個例子中, Car 類的構(gòu)造函數(shù)使用 this 指針來區(qū)分成員變量和構(gòu)造函數(shù)參數(shù)。同樣, setYear 成員函數(shù)使用 this 指針來返回調(diào)用該函數(shù)的對象的引用,這允許鏈?zhǔn)秸{(diào)用,如 myCar.setYear(2021).display(); 。在 main 函數(shù)中創(chuàng)建了 Car 類型的對象,并展示了如何使用這 些成員函數(shù)。

2.7.5?new關(guān)鍵字

C++中, new 關(guān)鍵字用于動態(tài)分配內(nèi)存。它是C++中處理動態(tài)內(nèi)存分配的主要工具之一,允許在程序運(yùn)行時根據(jù)需要分配內(nèi)存。

基本用法

分配單個對象:使用 new 可以在堆上動態(tài)分配一個對象。例如, new int 會分配一個 int 類型的空

間,并返回一個指向該空間的指針。

int* ptr = new int; //C語言中,int *p = (int *)malloc(sizeof(int));

分配對象數(shù)組new 也可以用來分配一個對象數(shù)組。例如, new int[10] 會分配一個包含10個整數(shù)的數(shù)組。

int* arr = new int [ 10 ]; //C 語言中, int *arr = (int *)malloc(sizeof(int)*10);

初始化:可以在 new 表達(dá)式中使用初始化。對于單個對象,可以使用構(gòu)造函數(shù)的參數(shù):

MyClass * obj = new MyClass ( arg1 , arg2 );

delete 配對使用

使用 new 分配的內(nèi)存必須顯式地通過 delete (對于單個對象)或 delete[] (對于數(shù)組)來釋放,以避免內(nèi)存泄露:

釋放單個對象:

delete ptr; // 釋放 ptr 指向的對象

釋放數(shù)組:

delete[] arr; // 釋放 arr 指向的數(shù)組

注意事項

異常安全:如果 new 分配內(nèi)存失敗,它會拋出 std::bad_alloc 異常。

內(nèi)存泄露:忘記釋放使用 new 分配的內(nèi)存會導(dǎo)致內(nèi)存泄露。

匹配使用 delete delete[ ] :為避免未定義行為,使用 new 分配的單個對象應(yīng)該使用

delete 釋放,使用 new[ ] 分配的數(shù)組應(yīng)該使用 delete[ ] 釋放。

示例代碼

class MyClass
{
public :
????????MyClass ()
????????{
????????????????std::cout << "Object created" << std::endl ;
????????}
};
int main ()
{
????????// 分配單個對象
????????MyClass * myObject = new MyClass ();
????????// 分配對象數(shù)組
????????int* myArray = new int [ 5 ]{ 1 , 2 , 3 , 4 , 5 };
????????// 使用對象和數(shù)組 ...
????????// 釋放內(nèi)存
????????delete myObject ;
????????delete [ ] myArray ;
????????return 0 ;
}

在這個例子中, new 被用來分配一個 MyClass 類型的對象和一個整數(shù)數(shù)組,然后使用 delete

delete[] 來釋放內(nèi)存。每個 new 都對應(yīng)一個 delete ,保證了動態(tài)分配的內(nèi)存被適當(dāng)管理。

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

2.8.1 什么是析構(gòu)函數(shù)

析構(gòu)函數(shù)是C++中的一個特殊的成員函數(shù),它在對象生命周期結(jié)束時被自動調(diào)用,用于執(zhí)行對象銷毀前的清理工作。析構(gòu)函數(shù)特別重要,尤其是在涉及動態(tài)分配的資源(如內(nèi)存、文件句柄、網(wǎng)絡(luò)連接等)的情況下。

基本特性

1. 名稱:析構(gòu)函數(shù)的名稱由波浪號( ~ )后跟類名構(gòu)成,如 ~MyClass() 。

2. 無返回值和參數(shù)析構(gòu)函數(shù)不接受任何參數(shù),也不返回任何值。

3. 自動調(diào)用:當(dāng)對象的生命周期結(jié)束時(例如,一個局部對象的作用域結(jié)束,或者使用 delete 刪除一個動態(tài)分配的對象),析構(gòu)函數(shù)會被自動調(diào)用。

4. 不可重載每個類只能有一個析構(gòu)函數(shù)。

5. 繼承和多態(tài):如果一個類是多態(tài)基類,其析構(gòu)函數(shù)應(yīng)該是虛的。

示例

假設(shè)我們有一個類 MyClass ,它包含了動態(tài)分配的內(nèi)存或其他資源:

輸出

在這個示例中, MyClass 的構(gòu)造函數(shù)分配了一塊內(nèi)存,而析構(gòu)函數(shù)釋放了這塊內(nèi)存。當(dāng) obj 的生命周期結(jié)束時(即離開了它的作用域), MyClass 的析構(gòu)函數(shù)被自動調(diào)用,負(fù)責(zé)清理資源,防止內(nèi)存泄露。

重要性

析構(gòu)函數(shù)在管理資源方面非常重要。沒有正確實現(xiàn)析構(gòu)函數(shù),可能導(dǎo)致資源泄露或其他問題。在基于RAII(資源獲取即初始化)原則的C++編程實踐中,確保資源在對象析構(gòu)時被適當(dāng)釋放是非常關(guān)鍵的。當(dāng)使用智能指針和其他自動資源管理技術(shù)時,可以減少顯式編寫析構(gòu)函數(shù)的需要,但了解析構(gòu)函數(shù)的工作原理仍然很重要。

以下是關(guān)于 C++ 中析構(gòu)函數(shù)需要了解的十個要點的表格:

2.9 靜態(tài)成員

2.9.1 靜態(tài)成員的定義

靜態(tài)成員在C++類中是一個重要的概念,它包括靜態(tài)成員變量和靜態(tài)成員函數(shù)。靜態(tài)成員的特點和存在的

意義如下:

靜態(tài)成員變量

1. 定義:靜態(tài)成員變量是類的所有對象共享的變量。與普通成員變量相比,無論創(chuàng)建了多少個類的實例,靜態(tài)成員變量只有一份拷貝。

2. 初始化:靜態(tài)成員變量需要在類外進(jìn)行初始化,通常在類的實現(xiàn)文件中。

3. 訪問:靜態(tài)成員變量可以通過類名直接訪問,不需要創(chuàng)建類的對象。也可以通過類的對象訪問。

4. 用途:常用于存儲類級別的信息(例如,計數(shù)類的實例數(shù)量)或全局?jǐn)?shù)據(jù)需要被類的所有實例共 享。

靜態(tài)成員函數(shù)

1. 定義:靜態(tài)成員函數(shù)是可以不依賴于類的實例而被調(diào)用的函數(shù)。它不能訪問類的非靜態(tài)成員變量和非靜態(tài)成員函數(shù)。

2. 訪問:類似于靜態(tài)成員變量,靜態(tài)成員函數(shù)可以通過類名直接調(diào)用,也可以通過類的實例調(diào)用。

3. 用途:常用于實現(xiàn)與具體對象無關(guān)的功能,或訪問靜態(tài)成員變量。

示例代碼

存在的意義

共享數(shù)據(jù):允許對象之間共享數(shù)據(jù),而不需要每個對象都有一份拷貝。

節(jié)省內(nèi)存:對于頻繁使用的類,使用靜態(tài)成員可以節(jié)省內(nèi)存。

獨立于對象的功能:靜態(tài)成員函數(shù)提供了一種在不創(chuàng)建對象的情況下執(zhí)行操作的方法,這對于實現(xiàn)

工具函數(shù)或管理類級別狀態(tài)很有用。

2.9.2 靜態(tài)成員變量的作用

靜態(tài)成員變量在C++中的一個典型應(yīng)用是用于跟蹤類的實例數(shù)量。這個案例體現(xiàn)了靜態(tài)成員變量的特性:

它們在類的所有實例之間共享,因此適合于存儲所有實例共有的信息。

下面是一個示例,展示了如何使用靜態(tài)成員變量來計數(shù)一個類的實例數(shù)量:

?在這個例子中:

Myclass 類有一個靜態(tài)成員變量 staticNumofInstance ,用來跟蹤該類的實例數(shù)量。

每當(dāng)創(chuàng)建 Myclass 的新實例時,構(gòu)造函數(shù)會增加 staticNumofInstance 。

每當(dāng)一個 Myclass 實例被銷毀時,析構(gòu)函數(shù)會減少 staticNumofInstance 。

通過靜態(tài)成員函數(shù) getNunofInstance 可以隨時獲取當(dāng)前的實例數(shù)量。

靜態(tài)成員變量 staticNumofInstance 在類外初始化為0。

這個案例展示了靜態(tài)成員變量如何在類的所有實例之間共享,并為所有實例提供了一個共同的狀態(tài)(在這個例子中是實例的數(shù)量)。這種技術(shù)在需要跟蹤對象數(shù)量或?qū)崿F(xiàn)某種形式的資源管理時特別有用。?

2.10 繼承

2.10.1 繼承基本概念

繼承是面向?qū)ο缶幊?#xff08;OOP)中的一個核心概念,特別是在C++中。它允許一個類(稱為派生類或子類)繼承另一個類(稱為基類或父類)的屬性和方法。繼承的主要目的是實現(xiàn)代碼重用,以及建立一種類型之間的層次關(guān)系。

特點

1. 代碼重用:子類繼承了父類的屬性和方法,減少了代碼的重復(fù)編寫。

2. 擴(kuò)展性:子類可以擴(kuò)展父類的功能,添加新的屬性和方法,或者重寫(覆蓋)現(xiàn)有的方法。

3. 多態(tài)性:通過繼承和虛函數(shù),C++支持多態(tài),允許在運(yùn)行時決定調(diào)用哪個函數(shù)。

基本用法

C++中,繼承可以是公有(public)、保護(hù)(protected)或私有(private)的,這決定了基類成員在派生類中的訪問權(quán)限。

輸出

在這個例子中, Bickle?類和Roadster類公有地繼承自 Vehicle 類,這意味著所有 Vehicle 類的公有成員在Bickle?類和Roadster類中也是公有的。

2.10.2 權(quán)限對繼承的影響

C++中,訪問控制符對繼承的影響可以通過下表來清晰地展示。這個表格展示了不同類型的繼承

public protected 、 private )如何影響基類的不同類型成員( public 、 protected

private )在派生類中的訪問級別。

解釋:

public 繼承:基類的 public 成員在派生類中仍然是 public 的, protected 成員仍然是

protected 的?;惖?private 成員在派生類中不可訪問。

protected 繼承:基類的 public protected 成員在派生類中都變成 protected 的。基類

private 成員在派生類中不可訪問。

private 繼承:基類的 public protected 成員在派生類中都變成 private 的?;惖?

private 成員在派生類中不可訪問。

這個表格提供了一個快速參考,幫助理解在不同類型的繼承中基類成員的訪問級別是如何變化的。記住,無論繼承類型如何,基類的 private 成員始終不可直接在派生類中訪問。

2.10.3 基類構(gòu)造函數(shù)

C++中,派生類可以通過其構(gòu)造函數(shù)的初始化列表來調(diào)用基類的構(gòu)造函數(shù)。這是在構(gòu)造派生類對象時初始化基類部分的標(biāo)準(zhǔn)做法

當(dāng)創(chuàng)建派生類的對象時,基類的構(gòu)造函數(shù)總是在派生類的構(gòu)造函數(shù)之前被調(diào)用。如果沒有明確指定,將調(diào)用基類的默認(rèn)構(gòu)造函數(shù)。如果基類沒有默認(rèn)構(gòu)造函數(shù),或者你需要調(diào)用一個特定的基類構(gòu)造函數(shù),需要在派生類構(gòu)造函數(shù)的初始化列表中明確指定。

輸出

2.10.4 虛函數(shù)

C++中, virtual override 關(guān)鍵字用于支持多態(tài),尤其是在涉及類繼承和方法重寫的情況下。正確地理解和使用這兩個關(guān)鍵字對于編寫可維護(hù)和易于理解的面向?qū)ο蟠a至關(guān)重要。

virtual 關(guān)鍵字

1. 使用場景:在基類中聲明虛函數(shù)。

2. 目的:允許派生類重寫該函數(shù),實現(xiàn)多態(tài)。

3. 行為:當(dāng)通過基類的指針或引用調(diào)用一個虛函數(shù)時,調(diào)用的是對象實際類型的函數(shù)版本。

override 關(guān)鍵字

1. 使用場景:在派生類中重寫虛函數(shù)。

2. 目的:明確指示函數(shù)意圖重寫基類的虛函數(shù)。

3. 行為:確保派生類的函數(shù)確實重寫了基類中的一個虛函數(shù)。如果沒有匹配的虛函數(shù),編譯器會報

錯。

輸出:自行車跑起來

注意點

只在派生類中使用 overrideoverride 應(yīng)僅用于派生類中重寫基類的虛函數(shù)。

虛析構(gòu)函數(shù):如果類中有虛函數(shù),通常應(yīng)該將析構(gòu)函數(shù)也聲明為虛的。

默認(rèn)情況下,成員函數(shù)不是虛的:在C++中,成員函數(shù)默認(rèn)不是虛函數(shù)。只有顯式地使用 virtual

關(guān)鍵字才會成為虛函數(shù)。

繼承中的虛函數(shù):一旦在基類中聲明為虛函數(shù),該函數(shù)在所有派生類中自動成為虛函數(shù),無論是否

使用 virtual 關(guān)鍵字。

正確使用 virtual override 關(guān)鍵字有助于清晰地表達(dá)程序員的意圖,并利用編譯器檢查來避免常

見的錯誤,如簽名不匹配導(dǎo)致的非預(yù)期的函數(shù)重寫。

2.10.5 多重繼承

C++中,多重繼承是一種允許一個類同時繼承多個基類的特性。這意味著派生類可以繼承多個基類的屬性和方法。多重繼承增加了語言的靈活性,但同時也引入了額外的復(fù)雜性,特別是當(dāng)多個基類具有相同的成員時。

基本概念

在多重繼承中,派生類繼承了所有基類的特性。這包括成員變量和成員函數(shù)。如果不同的基類有相同名稱的成員,則必須明確指出所引用的是哪個基類的成員。

示例

假設(shè)有兩個基類 ClassA ClassB ,以及一個同時從這兩個類繼承的派生類 Derived

class ClassA

{

public:

????????void displayA()

????????{

????????????????std::cout << "Displaying ClassA" << std::endl;

????????}

};

class ClassB

{

public:

????????void displayB()

????????{

????????????????std::cout << "Displaying ClassB" << std::endl;

????????}

};

class Derived : public ClassA, public ClassB

{

public:

????????void display()

????????{

????????????????displayA(); // 調(diào)用 ClassA displayA

????????????????displayB(); // 調(diào)用 ClassB displayB

????????}

};

int main()

{

????????Derived obj;

????????obj.displayA(); // 調(diào)用 ClassA displayA

????????obj.displayB(); // 調(diào)用 ClassB displayB

????????obj.display(); // 調(diào)用 Derived display

????????return 0;

}

在這個示例中, Derived 類同時繼承了 ClassA ClassB 。因此,它可以使用這兩個類中定義的方法。

在這個實例中,如果不同的基類有相同名稱的成員,則必須明確指出所引用的是哪個基類的成員。

注意事項

菱形繼承問題:如果兩個基類繼承自同一個更高層的基類,這可能導(dǎo)致派生類中存在兩份基類的副

本,稱為菱形繼承(或鉆石繼承)問題。這可以通過虛繼承來解決。

復(fù)雜性:多重繼承可能會使類的結(jié)構(gòu)變得復(fù)雜,尤其是當(dāng)繼承層次較深或類中有多個基類時。

設(shè)計考慮:雖然多重繼承提供了很大的靈活性,但過度使用可能導(dǎo)致代碼難以理解和維護(hù)。在一些

情況下,使用組合或接口(純虛類)可能是更好的設(shè)計選擇。

多重繼承是C++的一個強(qiáng)大特性,但應(yīng)謹(jǐn)慎使用。合理地應(yīng)用多重繼承可以使代碼更加靈活和強(qiáng)大,但不當(dāng)?shù)氖褂每赡軐?dǎo)致設(shè)計上的問題和維護(hù)困難。

2.10.6 虛繼承

虛繼承是C++中一種特殊的繼承方式,主要用來解決多重繼承中的菱形繼承問題。在菱形繼承結(jié)構(gòu)中,一個類繼承自兩個具有共同基類的類時,會導(dǎo)致共同基類的成員在派生類中存在兩份拷貝,這不僅會導(dǎo)致資源浪費,還可能引起數(shù)據(jù)不一致的問題。虛繼承通過確保共同基類的單一實例存在于繼承層次中,來解決這一問題。

菱形繼承問題示例

考慮以下的類結(jié)構(gòu):

class Base

{

public:

????????int data;

};

class Derived1 : public Base

{

????????// 繼承自 Base

};

class Derived2 : public Base

{

????????// 繼承自 Base

};

class FinalDerived : public Derived1, public Derived2

{

????????// 繼承自 Derived1 Derived2

};

在這個例子中, FinalDerived 類通過 Derived1 Derived2 間接地繼承自 Base 類兩次。因此,

它包含了兩份 Base 的成員拷貝。

使用虛繼承解決菱形繼承問題

要解決這個問題,應(yīng)使用虛繼承:

class Base

{

public:

????????int data;

};

class Derived1 : virtual public Base

{

????????// 虛繼承 Base

};

class Derived2 : virtual public Base

{

????????// 虛繼承 Base

};

class FinalDerived : public Derived1, public Derived2

{

????????// 繼承自 Derived1 Derived2

};

通過將 Derived1 Derived2 Base 的繼承聲明為虛繼承( virtual public Base ),

FinalDerived 類中只會有一份 Base 類的成員。無論通過 Derived1 還是 Derived2 的路徑,訪問

的都是同一個 Base 類的成員。

特點和注意事項

初始化虛基類:在使用虛繼承時,虛基類(如上例中的 Base 類)只能由最派生的類(如

FinalDerived )初始化。

內(nèi)存布局:虛繼承可能會改變類的內(nèi)存布局,通常會增加額外的開銷,比如虛基類指針。

設(shè)計考慮:虛繼承應(yīng)謹(jǐn)慎使用,因為它增加了復(fù)雜性。在實際應(yīng)用中,如果可以通過其他設(shè)計(如

組合或接口)避免菱形繼承,那通常是更好的選擇。

虛繼承是C++語言中處理復(fù)雜繼承關(guān)系的一種重要機(jī)制,但它也帶來了一定的復(fù)雜性和性能考慮。正確地使用虛繼承可以幫助你建立清晰、有效的類層次結(jié)構(gòu)。

2.11 多態(tài)

多態(tài)的基本概念(polymorphic)

想象一下,你有一個遙控器(這就像是一個基類的指針),這個遙控器可以控制不同的電子設(shè)備(這些設(shè)備就像是派生類)。無論是電視、音響還是燈光,遙控器上的“/關(guān)按鈕(這個按鈕就像是一個虛函數(shù))都能控制它們,但具體的操作(打開電視、播放音樂、開燈)則取決于你指向的設(shè)備。

2.11.1 如何實現(xiàn)多態(tài)

1. 使用虛函數(shù)(Virtual Function

我們在基類中定義一個虛函數(shù),這個函數(shù)可以在任何派生類中被重寫或者說定制。

使用關(guān)鍵字 virtual 來聲明。

2. 創(chuàng)建派生類并重寫虛函數(shù)

在派生類中,我們提供該虛函數(shù)的具體實現(xiàn)。這就像是告訴遙控器,當(dāng)你控制我的這個設(shè)備

時,這個按鈕應(yīng)該這樣工作

3. 通過基類的引用或指針調(diào)用虛函數(shù)

當(dāng)我們使用基類類型的指針或引用來調(diào)用虛函數(shù)時,實際調(diào)用的是對象的實際類型(派生類)

中的函數(shù)版本。

在這個例子中,不同的對象( TvRemoteCon TvRemoteCon )以它們自己的方式,盡管調(diào)用的是相同的函數(shù) openUtils 。這就是多態(tài)的魅力——相同的接口,不同的行為。

為什么使用多態(tài)

靈活性:允許我們編寫可以處理不確定類型的對象的代碼。

可擴(kuò)展性:我們可以添加新的派生類而不必修改使用基類引用或指針的代碼。

接口與實現(xiàn)分離:我們可以設(shè)計一個穩(wěn)定的接口,而將具體的實現(xiàn)留給派生類去處理。

2.11.2 抽象類

抽象類的基本概念

想象一下,你有一個交通工具的概念。這個概念告訴你所有交通工具都應(yīng)該能做什么,比如移動

move),但它并不具體說明怎么移動。對于不同的交通工具,比如汽車和自行車,它們的移動方式是不同的。在這個意義上,“交通工具是一個抽象的概念,因為它本身并不能直接被使用。你需要一個具體的交通工具,比如“汽車自行車,它們根據(jù)交通工具的概念具體實現(xiàn)了移動的功能。

C++ 中,抽象類就像是這樣的一個抽象概念。它定義了一組方法(比如移動),但這些方法可能沒有具體的實現(xiàn)。這意味著,抽象類定義了派生類應(yīng)該具有的功能,但不完全實現(xiàn)這些功能。

抽象類的特點

1. 包含至少一個純虛函數(shù)

抽象類至少有一個純虛函數(shù)。這是一種特殊的虛函數(shù),在抽象類中沒有具體實現(xiàn),而是留給派

生類去實現(xiàn)。

純虛函數(shù)的聲明方式是在函數(shù)聲明的末尾加上 = 0 。

2. 不能直接實例化

由于抽象類不完整,所以不能直接創(chuàng)建它的對象。就像你不能直接使用交通工具的概念去任

何地方,你需要一個具體的交通工具。

3. 用于提供基礎(chǔ)結(jié)構(gòu)

抽象類的主要目的是為派生類提供一個共同的基礎(chǔ)結(jié)構(gòu),確保所有派生類都有一致的接口和行

為。

#include <iostream>

using namespace std;

class Teacher

{

public:

????????string name;

????????string shool;

????????string major;

????????virtual void goInClass() = 0;

????????virtual void startTeaching() = 0;

????????virtual void afterTeaching() = 0;

};

class EnglishTeacher : public Teacher

{

public:

????????void goInClass() override

????????{

????????????????cout << "英語老師開始進(jìn)入教室" << endl;

????????}

????????void startTeaching() override

????????{

????????????????cout << "英語老師開始教學(xué)" << endl;

????????}

????????void afterTeaching() override

????????{

????????};

};

class ProTeacher : public Teacher

{

public:

????????void goInClass() override

????????{

????????????????cout << "編程老師開始進(jìn)入教室" << endl;

????????}

????????void startTeaching() override

????????{

????????????????cout << "編程老師開始擼代碼了,拒絕讀PPT" << endl;

????????}

????????void afterTeaching() override

????????{

????????????????cout << "編程老師下課后手把手教x學(xué)員寫代碼" << endl;

????????};

};

int main()

{

????????// Teacher t;//抽象類,不支持被實例化

????????EnglishTeacher e;

????????e.goInClass();

????????ProTeacher t;

????????t.startTeaching();

????????t.afterTeaching();

????????//抽象類,多態(tài)

????????Teacher *teacher = new ProTeacher;

????????teacher->startTeaching();

????????return 0;

}

2.12 模版

C++ 中,模板(Template)是一種通用的編程工具,允許程序員編寫泛型代碼,使得類或函數(shù)能夠適用于多種不同的數(shù)據(jù)類型而不需要重復(fù)編寫相似的代碼。C++ 提供了兩種主要類型的模板:類模板和函數(shù)模板。

類模板(Class Templates):

類模板允許定義通用的類,其中某些類型可以作為參數(shù)。這樣的類可以處理不同類型的數(shù)據(jù),而不需要為每個數(shù)據(jù)類型編寫單獨的類。

#include <iostream>using namespace std;class PrintInt
{
private:int data;
public:void printInt(){cout << data <<endl;}void setInt(int data){this->data = data;}
};class PrintString
{
private:string data;
public:void printString(){cout << data <<endl;}void setString(string data){this->data = data;}
};template<typename T>
class PrintT
{
private:T data;
public:void printT(){cout << data <<endl;}void setT(T data){this->data = data;}
};int main()
{PrintInt p1;p1.setInt(10);p1.printInt();PrintString p2;p2.setString("chenzhuo");p2.printString();PrintT<int> p3;p3.setT(10);p3.printT();PrintT<string> p4;p4.setT("dashuaige");p4.printT();return 0;
}

?輸出

http://www.risenshineclean.com/news/12078.html

相關(guān)文章:

  • 河南的網(wǎng)絡(luò)推廣公司專業(yè)黑帽seo推廣
  • 越秀區(qū)網(wǎng)站建設(shè)寧波seo搜索引擎優(yōu)化公司
  • 電商網(wǎng)站技術(shù)方案阿里指數(shù)官網(wǎng)最新版本
  • wordpress邊下邊看seo權(quán)重優(yōu)化軟件
  • 網(wǎng)站里面如何做下載的app全國31省市疫情最新消息今天
  • html電子商務(wù)網(wǎng)站模板百度信息流推廣教程
  • 網(wǎng)站做支付功能培訓(xùn)計劃和培訓(xùn)內(nèi)容
  • 用自己的電腦做網(wǎng)站需要備案嗎旅游最新資訊
  • 網(wǎng)站建設(shè)jutuibao線上推廣的渠道和方法
  • 媒體公司網(wǎng)站模板百度指數(shù)1000搜索量有多少
  • 怎么做網(wǎng)站像淘寶這樣的免費發(fā)布產(chǎn)品信息的網(wǎng)站
  • 廣州的一起做網(wǎng)站網(wǎng)絡(luò)軟文廣告
  • 幫客戶做網(wǎng)站內(nèi)容網(wǎng)頁關(guān)鍵詞排名優(yōu)化
  • 免費自助建站系統(tǒng)平臺 貼吧網(wǎng)站分析工具
  • 廣州網(wǎng)站設(shè)計我選刻在線識別圖片來源
  • 自貢做網(wǎng)站的公司百度官網(wǎng)認(rèn)證申請
  • 有沒有專門做航拍婚禮網(wǎng)站公司網(wǎng)站建設(shè)公司
  • 現(xiàn)在個人做網(wǎng)站還能盈利營銷策略有哪些方法
  • 出國越南做網(wǎng)站8000保底seo是什么專業(yè)的課程
  • 保定網(wǎng)站 優(yōu)百度關(guān)鍵詞模擬點擊軟件
  • 查詢系統(tǒng)網(wǎng)站模板電商網(wǎng)站鏈接買賣
  • 獨立商城系統(tǒng)網(wǎng)站建設(shè)站長工具ping檢測
  • 重慶網(wǎng)站產(chǎn)品推廣汕頭網(wǎng)站制作設(shè)計
  • 怎么用自己電腦做服務(wù)器搭建網(wǎng)站深圳龍華區(qū)大浪社區(qū)
  • 網(wǎng)站注冊人查詢某個產(chǎn)品營銷推廣方案
  • 保險官方網(wǎng)站如何進(jìn)行品牌營銷
  • 聽完米課做的網(wǎng)站網(wǎng)絡(luò)營銷公司好不好
  • 買了域名怎么用免費seo教程
  • 品牌高端網(wǎng)站建設(shè)公司網(wǎng)絡(luò)公司網(wǎng)頁設(shè)計
  • 做傳銷網(wǎng)站違法嗎自己搭建網(wǎng)站需要什么