C++學習筆記五

C++繼承

//基類
class Animal{};//派生類
class Dog : public Animal{};

#include<iostearm>
using namespace std;//基類
class Shape{public:void setwidth(int w){width = w;}void setheight(int h){height = h;}protected:int width;int height;}//派生類
class Rectangle : public Shape{public:int getarea(){return width * height;}}int main(void){Rectangle Rect;Rect.setwidth(5);Rect.setheight(7);// 輸出對象的面積cout << "Total area: " << Rect.getArea() << endl;return 0;}

訪問控制與繼承

多繼承

多繼承即一個子類可以有多個父類,它繼承了多個父類的特性。

C++ 類可以從多個類繼承成員

class <派生類名>:<繼承方式1><基類名1>,<繼承方式2><基類名2>,…
{
<派生類類體>
};

C++重載運算符和重載函數

C++ 允許在同一作用域中的某個函數運算符指定多個定義,分別稱為函數重載運算符重載

重載聲明是指一個與之前已經在該作用域內聲明過的函數或方法具有相同名稱的聲明,但是它們的參數列表和定義(實現)不相同。

當調用一個重載函數重載運算符時,編譯器通過把所使用的參數類型與定義中的參數類型進行比較,決定選用最合適的定義。選擇最合適的重載函數或重載運算符的過程,稱為重載決策

函數重載

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

#include<iostearm>
using namespace std;class printdata{public:void print(int i) {cout << "整數為: " << i << endl;}void print(double  f) {cout << "浮點數為: " << f << endl;}void print(char c[]) {cout << "字符串為: " << c << endl;}}int main(void)
{printdata pd;// 輸出整數pd.print(5);// 輸出浮點數pd.print(500.263);// 輸出字符串char c[] = "Hello C++";pd.print(c);return 0;
}

運算符重載

Box operator+(const Box&);
Box operator+(const Box&, const Box&);

#include <iostream>
using namespace std;class Box
{public:double getVolume(void){return length * breadth * height;}void setLength( double len ){length = len;}void setBreadth( double bre ){breadth = bre;}void setHeight( double hei ){height = hei;}// 重載 + 運算符,用于把兩個 Box 對象相加Box operator+(const Box& b){Box box;box.length = this->length + b.length;box.breadth = this->breadth + b.breadth;box.height = this->height + b.height;return box;}private:double length;      // 長度double breadth;     // 寬度double height;      // 高度
};
// 程序的主函數
int main( )
{Box Box1;                // 聲明 Box1,類型為 BoxBox Box2;                // 聲明 Box2,類型為 BoxBox Box3;                // 聲明 Box3,類型為 Boxdouble volume = 0.0;     // 把體積存儲在該變量中// Box1 詳述Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0);// Box2 詳述Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0);// Box1 的體積volume = Box1.getVolume();cout << "Volume of Box1 : " << volume <<endl;// Box2 的體積volume = Box2.getVolume();cout << "Volume of Box2 : " << volume <<endl;// 把兩個對象相加,得到 Box3Box3 = Box1 + Box2;// Box3 的體積volume = Box3.getVolume();cout << "Volume of Box3 : " << volume <<endl;return 0;
}

C++多態

當類之間存在層次結構,并且類之間是通過繼承關聯時,就會用到多態。

C++ 多態允許使用基類指針或引用來調用子類的重寫方法,從而使得同一接口可以表現不同的行為。多態使得代碼更加靈活和通用,程序可以通過基類指針或引用來操作不同類型的對象,而不需要顯式區分對象類型。這樣可以使代碼更具擴展性,在增加新的形狀類時不需要修改主程序。

例如,假設有一個基類?Shape?和派生類?CircleRectangle,它們都實現了?draw()?方法。通過多態,我們可以統一調用?draw()?方法,而具體繪制的是圓形還是矩形則由對象的實際類型決定。

class Math {
public:int add(int a, int b) { return a + b; }           // 整數加法double add(double a, double b) { return a + b; } // 浮點數加法
};// 使用示例
Math m;
m.add(1, 2);     // 調用 add(int, int)
m.add(1.5, 2.5); // 調用 add(double, double)

C++數據抽象

C++ 類為數據抽象提供了可能。它們向外界提供了大量用于操作對象數據的公共方法,也就是說,外界實際上并不清楚類的內部實現。實現了內部與外部的分離

#include<iostearm>
using namespace std;int main(){cout << "hello world" << endl;//此處并不需要cout是如何實現的,調用即可return 0;}

實例(有成員?addNum?和?getTotal?是對外的接口,用戶需要知道它們以便使用類。私有成員?total?是用戶不需要了解的,但又是類能正常工作所必需的):

#include<iostearm>
using namespace std;class Adder{public://構造函數Adder(int i = 0){total = i;}//對外的接口void addNum(int number){total += number;}//對外的接口int gettotal(){return total;}private://對外隱藏的數據int total;}int main(){Adder a;a.addNum(10);a.addNum(20);a.addNum(30);cout << "total is " << a.gettotal() << endl;return 0;}

C++接口(抽象類)

接口描述了類的行為和功能,而不需要完成類的特定實現。

C++ 接口是使用抽象類來實現的,抽象類與數據抽象互不混淆,數據抽象是一個把實現細節與相關的數據分離開的概念。

如果類中至少有一個函數被聲明為純虛函數,則這個類就是抽象類。純虛函數是通過在聲明中使用 "= 0" 來指定的

class BOX
{public://純虛函數virtual double getvolume() = 0;private:double length;double breadth;double height;}

設計抽象類(通常稱為 ABC)的目的,是為了給其他類提供一個可以繼承的適當的基類。抽象類不能被用于實例化對象,它只能作為接口使用。

C++文件和流

C++ 中另一個標準庫?fstream,它定義了三個新的數據類型:

要在 C++ 中進行文件處理,必須在 C++ 源代碼文件中包含頭文件 <iostream> 和 <fstream>。

open()?成員函數的第一參數指定要打開的文件的名稱和位置,第二個參數定義文件被打開的模式。

void open(const char *filename, ios::openmode mode);

可以把以上兩種或兩種以上的模式結合使用。例如,如果想要以寫入模式打開文件,并希望截斷文件,以防文件已存在,那么可以使用下面的語法:

ofstream outfile;
outfile.open("file.dat", ios::out | ios::trunc );

如果想要打開一個文件用于讀寫

ifstream  afile;
afile.open("file.dat", ios::out | ios::in );

寫入文件

在 C++ 編程中,我們使用流插入運算符( << )向文件寫入信息,就像使用該運算符輸出信息到屏幕上一樣。唯一不同的是,在這里您使用的是?ofstream?或?fstream?對象,而不是?cout?對象。

讀取文件

在 C++ 編程中,我們使用流提取運算符( >> )從文件讀取信息,就像使用該運算符從鍵盤輸入信息一樣。唯一不同的是,在這里您使用的是?ifstream?或?fstream?對象,而不是?cin?對象。

C++異常處理

異常是程序在執行期間產生的問題。C++ 異常是指在程序運行時發生的特殊情況,比如嘗試除以零的操作。

異常提供了一種轉移程序控制權的方式。C++ 異常處理涉及到三個關鍵字:try、catch、throw

  • throw:?當問題出現時,程序會拋出一個異常。這是通過使用?throw?關鍵字來完成的。
  • catch:?在您想要處理問題的地方,通過異常處理程序捕獲異常。catch?關鍵字用于捕獲異常。
  • try:?try?塊中的代碼標識將被激活的特定異常。它后面通常跟著一個或多個 catch 塊。
try
{// 保護代碼
}catch( ExceptionName e1 )
{// catch 塊
}catch( ExceptionName e2 )
{// catch 塊
}catch( ExceptionName eN )
{// catch 塊
}
double division(int a, int b)
{if( b == 0 ){throw "Division by zero condition!";}return (a/b);
}

C++動態內存

  • 棧:在函數內部聲明的所有變量都將占用棧內存。
  • 堆:這是程序中未使用的內存,在程序運行時可用于動態分配內存

可以使用特殊的運算符為給定類型的變量在運行時分配堆內的內存,這會返回所分配的空間地址。這種運算符即?new?運算符。

不再需要動態分配的內存空間,可以使用?delete?運算符,刪除之前由 new 運算符分配的內存。

new和delete運算符

我們可以定義一個指向 double 類型的指針,然后請求內存,該內存在執行時被分配

double* pvalue  = NULL; // 初始化為 null 的指針
pvalue  = new double;   // 為變量請求內存

如果自由存儲區已被用完,可能無法成功分配內存。所以建議檢查 new 運算符是否返回 NULL 指針,并采取以下適當的操作:

double* pvalue  = NULL;
if( !(pvalue  = new double ))
{cout << "Error: out of memory." <<endl;exit(1);}

在任何時候,當您覺得某個已經動態分配內存的變量不再需要使用時,您可以使用 delete 操作符釋放它所占用的內存,如下所示:

delete pvalue;        // 釋放 pvalue 所指向的內存

數組的動態內存分配

假設我們要為一個字符數組(一個有 20 個字符的字符串)分配內存,我們可以使用上面實例中的語法來為數組動態地分配內存,如下所示:

char* pvalue  = NULL;   // 初始化為 null 的指針
pvalue  = new char[20]; // 為變量請求內存

要刪除我們剛才創建的數組,語句如下

delete [] pvalue;        // 刪除 pvalue 所指向的數組

C++預處理器

預處理器是一些指令,指示編譯器在實際編譯之前所需完成的預處理。

#define 預處理

用于創建符號常量。該符號常量通常稱為

#include <iostream>
using namespace std;#define PI 3.14159int main ()
{cout << "Value of PI :" << PI << endl; return 0;
}

參數宏

可以使用 #define 來定義一個帶有參數的宏

#include <iostream>
using namespace std;#define MIN(a,b) (a<b ? a : b)int main ()
{int i, j;i = 100;j = 30;cout <<"較小的值為:" << MIN(i, j) << endl;return 0;
}

條件編譯

有幾個指令可以用來有選擇地對部分程序源代碼進行編譯。這個過程被稱為條件編譯。

#ifdef NULL#define NULL 0
#endif
#ifdef DEBUGcerr <<"Variable x = " << x << endl;
#endif

# 和 ## 運算符

# 運算符會把 replacement-text 令牌轉換為用引號引起來的字符串。

#include <iostream>
using namespace std;#define MKSTR( x ) #xint main ()
{cout << MKSTR(HELLO C++) << endl;return 0;
}

會出現這行結果:cout << MKSTR(HELLO C++) << endl;
變成了cout << "HELLO C++" << endl;

## 運算符用于連接兩個令牌

#include <iostream>
using namespace std;#define concat(a, b) a ## b
int main()
{int xy = 100;cout << concat(x, y);return 0;
}

會出現這行結果:100;將cout << concat(x, y);
變成了100;

C++多線程

線程是程序中的輕量級執行單元,允許程序同時執行多個任務。

多線程是多任務處理的一種特殊形式,多任務處理允許讓電腦同時運行兩個或兩個以上的程序。

一般情況下,兩種類型的多任務處理:基于進程和基于線程

  • 基于進程的多任務處理是程序的并發執行。
  • 基于線程的多任務處理是同一程序的片段的并發執行。

并發 (Concurrency) 與并行 (Parallelism)

  • 并發:多個任務在時間片段內交替執行,表現出同時進行的效果。
  • 并行:多個任務在多個處理器或處理器核上同時執行

使用函數指針創建線程

#include <iostream>
#include <thread>void printMessage(int count) {for (int i = 0; i < count; ++i) {std::cout << "Hello from thread (function pointer)!\n";}
}int main() {std::thread t1(printMessage, 5); // 創建線程,傳遞函數指針和參數t1.join(); // 等待線程完成return 0;
}

線程管理

join()

join() 用于等待線程完成執行。如果不調用 join() 或 detach() 而直接銷毀線程對象,會導致程序崩潰。

t.join();

detach()

detach() 將線程與主線程分離,線程在后臺獨立運行,主線程不再等待它。

t.detach();

線程傳參

參數可以通過值傳遞給線程:

std::thread t(func, arg1, arg2);

線程同步與互斥

在多線程編程中,線程同步與互斥是兩個非常重要的概念,它們用于控制多個線程對共享資源的訪問,以避免數據競爭、死鎖等問題。

1. 互斥量(Mutex)

互斥量是一種同步原語,用于防止多個線程同時訪問共享資源。當一個線程需要訪問共享資源時,它首先需要鎖定(lock)互斥量。如果互斥量已經被其他線程鎖定,那么請求鎖定的線程將被阻塞,直到互斥量被解鎖(unlock)。

#include <mutex>std::mutex mtx; // 全局互斥量void safeFunction() {mtx.lock(); // 請求鎖定互斥量// 訪問或修改共享資源mtx.unlock(); // 釋放互斥量
}int main() {std::thread t1(safeFunction);std::thread t2(safeFunction);t1.join();t2.join();return 0;
}

2. 鎖(Locks)

C++提供了多種鎖類型,用于簡化互斥量的使用和管理。

常見的鎖類型包括:

  • std::lock_guard:作用域鎖,當構造時自動鎖定互斥量,當析構時自動解鎖。
  • std::unique_lock:與std::lock_guard類似,但提供了更多的靈活性,例如可以轉移所有權和手動解鎖。

3. 條件變量(Condition Variable)

條件變量用于線程間的協調,允許一個或多個線程等待某個條件的發生。它通常與互斥量一起使用,以實現線程間的同步。

std::condition_variable用于實現線程間的等待和通知機制。

#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void workerThread() {std::unique_lock<std::mutex> lk(mtx);cv.wait(lk, []{ return ready; }); // 等待條件// 當條件滿足時執行工作
}void mainThread() {{std::lock_guard<std::mutex> lk(mtx);// 準備數據ready = true;} // 離開作用域時解鎖cv.notify_one(); // 通知一個等待的線程
}

線程間通信

std::future 和 std::promise:實現線程間的值傳遞。

std::promise<int> p;
std::future<int> f = p.get_future();std::thread t([&p] {p.set_value(10); // 設置值,觸發 future
});int result = f.get(); // 獲取值

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914895.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914895.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914895.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AndroidStudio環境搭建

一、AndroidStudio下載 正常百度出來的站會自動翻譯成中文&#xff0c;導致歷史版本的界面總是顯示不出可下載的地方&#xff0c;點擊成切回英文&#xff0c;就能看出了。 歷史版本&#xff1a;https://developer.android.google.cn/studio/archive

Java大廠面試實錄:從Spring Boot到AI大模型的深度技術拷問

場景&#xff1a;互聯網大廠Java后端面試 面試官&#xff08;嚴肅&#xff09;&#xff1a;小曾&#xff0c;請坐。今天主要考察Java后端技術棧&#xff0c;包括微服務、大數據、AI等。我們先從簡單問題開始。 小曾&#xff08;搓手&#xff09;&#xff1a;好嘞&#xff01;面…

深入解析Hadoop中的HDFS架構設計

HDFS概述與核心設計原則作為Hadoop生態系統的基石&#xff0c;HDFS&#xff08;Hadoop Distributed File System&#xff09;是一種專為大規模數據處理而設計的分布式文件系統。它的核心設計理念源于對互聯網時代數據特征的深刻洞察——數據規模呈指數級增長&#xff0c;而硬件…

ota之.加密算法,mcu加密方式

一、ota之.加密算法&#xff0c;mcu加密方式 前面一篇文章&#xff0c;講了soc的加密方式&#xff0c;但是soc資源充足&#xff0c;mcu沒有&#xff0c;所以不會用openss生成公私鑰 切計算哈希用rsa256位。 ECC&#xff08;橢圓曲線加密&#xff09; 是一種非對稱加密算法&…

LangChain面試內容整理-知識點23:實戰案例:檢索增強生成(RAG)系統

檢索增強生成(Retrieval-Augmented Generation, RAG)是一種將LLM與外部知識庫結合的方法,通過實時檢索相關信息來輔助生成答案。這極大緩解了LLM“封閉知識”過期或不足的問題。LangChain非常適合構建RAG系統,因為它提供了文檔加載、向量存儲、檢索接口、LLM組合的一站式方…

探索阿里云ESA:開啟邊緣安全加速新時代

阿里云 ESA 是什么&#xff1f;阿里云 ESA&#xff0c;全稱邊緣安全加速&#xff08;Edge Security Acceleration&#xff09; &#xff0c;其前身為全站加速 DCDN&#xff08;Dynamic Content Delivery Network&#xff09;。在 2024 年 9 月 30 日&#xff0c;阿里云完成了這…

醋酸鈰:賦能科技創新的稀土之力

一、什么是醋酸鈰醋酸鈰是鈰元素與醋酸根離子形成的化合物。鈰作為稀土元素中的重要一員&#xff0c;廣泛應用于材料科學、催化劑、電子產品等領域。醋酸鈰以無色結晶或淺黃色結晶的形式存在&#xff0c;是鈰的有機鹽之一。它不僅具有穩定的化學性質&#xff0c;而且在某些特定…

數據結構之普利姆算法

前言&#xff1a;Prim算法是圖論中的算法&#xff0c;用來生成圖的最小生成樹。本篇文章介紹算法的流程&#xff0c;實現思想&#xff0c;和具體代碼實現&#xff0c;使用c語言。學習需要輸出才能理解的更透徹&#xff0c;所以說堅持寫文章&#xff0c;希望可以用自己的方式把一…

構建強大的物聯網架構所需了解的一切

數據正驅動著當今的商業發展&#xff0c;而物聯網&#xff08;IoT&#xff09;則有助于為企業的增長和創新開辟新的機遇。麥肯錫的研究表明&#xff0c;全球數據在四年內實現了驚人的 7 倍增長。隨著越來越多的物聯網設備進入市場&#xff0c;更多企業開始需要強大的物聯網架構…

java之json轉excel生成

背景 業務為實現自定義樣式excel的導出&#xff0c;常規的做法就是根據數據在代碼中進行類似模版的配置&#xff1b;這樣的體驗不是很好&#xff0c;只要用戶改變下樣式的設置不用代碼改動就能實現自定義excel的導出更加靈活。 以下是具體實現 pom依賴 <dependency><g…

新版本Cursor中配置自定義MCP服務器教程,附MCP工具開發實戰源碼

在 Cursor 中配置自定義 MCP 服務器&#xff1a;打造你的 AI 開發工具鏈 引言 隨著 AI 編程助手的普及&#xff0c;開發者們越來越希望能夠定制化自己的開發環境。Cursor 作為一款強大的 AI 編程編輯器&#xff0c;提供了 Model Context Protocol (MCP) 支持&#xff0c;新版本…

前端面試十二之vue3基礎

一、ref和reactive在 Vue 3 中&#xff0c;ref 和 reactive 是兩種主要的響應式數據創建方式&#xff0c;它們各有特點和適用場景。1.refref 主要用于創建單個值的響應式引用&#xff0c;通常用于基本類型數據&#xff0c;如數字、字符串等。使用 ref 創建的引用對象可以通過 .…

設計模式四:裝飾模式(Decorator Pattern)

裝飾模式是一種結構型設計模式&#xff0c;它允許你動態地給一個對象添加額外的職責&#xff0c;相比繼承更加靈活。1. 模式定義裝飾模式&#xff1a;動態地給一個對象添加一些額外的職責。就增加功能來說&#xff0c;裝飾模式相比生成子類更為靈活。2. 模式結構主要角色&#…

神經網絡常見激活函數 14-Mish函數

文章目錄Mish函數導函數函數和導函數圖像優缺點PyTorch 中的 Mish 函數TensorFlow 中的 Mish 函數Mish 論文 https://arxiv.org/pdf/1908.08681 函數導函數 Mish函數 Mish(x)x?tanh??(softplus(x))x?tanh??(ln??(1ex))\begin{aligned} \text{Mish}(x) & x \cdot \t…

LAMP遷移LNMP Nginx多站點配置全流程

文章目錄前言備份與停止服務nginx安裝與配置nginx 編譯安裝配置服務php-fpm多站點配置phf-fpm介紹多站點配置nginx 多站點配置nginx ssl 配置參考前言 之前服務器使用的是 LAMP環境&#xff0c;想充分利用服務器資源&#xff0c;再運行另外一個站點 在LAMP環境下應該是也可以…

Nginx屏蔽國外IP訪問

下載IP列表 # 下載到文件 wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest # 直接輸出到終端 curl -sSL https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest得到一份國內IP配置 # 原始IP列表格式&#xff1a;apnic|CN|ipv4|218.78.0.0|1310…

stl-string模擬

1.介紹主要進行cpp中string的模擬&#xff0c;方便我們更好的對stl進行使用&#xff0c;string沒有模板&#xff0c;我們將頭文件和函數寫在兩個不同的文件2.頭文件3.cpp文件如有問題&#xff0c;歡迎糾正&#xff01;

基于MATLAB的極限學習機ELM的數據回歸預測方法應用

說明&#xff1a;這是一個機器學習實戰項目&#xff08;附帶數據代碼文檔&#xff09;&#xff0c;如需數據代碼文檔可以直接到文章最后關注獲取 或者私信獲取。 1.項目背景 在當今的數據驅動時代&#xff0c;準確且高效的預測模型對于解決復雜問題至關重要。極限學習機&#…

芯谷科技--雙四通道模擬/數字多路復用器74HC4052

在電子系統中&#xff0c;信號的多路復用與解復用是常見的需求&#xff0c;特別是在需要對多個信號源進行選擇和切換的場景中。芯谷科技推出的 74HC4052 雙四通道模擬/數字多路復用器/解復用器&#xff0c;以其高效、靈活的設計&#xff0c;為工程師提供了可靠的解決方案。產品…

基于MATLAB的極限學習機ELM的數據分類預測方法應用

說明&#xff1a;這是一個機器學習實戰項目&#xff08;附帶數據代碼文檔&#xff09;&#xff0c;如需數據代碼文檔可以直接到文章最后關注獲取 或者私信獲取。 1.項目背景 在現代數據挖掘與機器學習領域&#xff0c;面對日益復雜的數據結構和快速增長的數據量&#xff0c;開…