「C++系列」C++ 修飾符類型

文章目錄

  • 一、C++ 修飾符類型
    • 1. 訪問修飾符(Access Modifiers)
    • 2. 存儲類修飾符(Storage Class Specifiers)
    • 3. 類型修飾符(Type Modifiers)
    • 4. 函數修飾符
  • 二、C++ 修飾符類型-案例
    • 1. 訪問修飾符案例
    • 2. 存儲類修飾符案例
    • 3. 類型修飾符案例
    • 4. 函數修飾符案例
  • 三、C++ 中的類型限定符
    • 1. `const` 限定符
    • 2. `volatile` 限定符
  • 四、相關鏈接

在這里插入圖片描述

一、C++ 修飾符類型

在C++中,修飾符(Modifiers)用于改變變量、函數、類成員等的默認行為或屬性。這些修飾符可以分為幾個主要的類別,包括訪問修飾符(Access Modifiers)、存儲類修飾符(Storage Class Specifiers)、類型修飾符(Type Modifiers)以及函數修飾符(如constnoexcept用于函數)。下面是對這些修飾符類型的一些簡要說明:

1. 訪問修飾符(Access Modifiers)

訪問修飾符控制類成員的訪問權限。

  • public:類外部可以訪問。
  • protected:只能被其派生類以及該類的成員訪問。
  • private:只能被該類內部的成員函數、友元函數以及類本身訪問。

2. 存儲類修飾符(Storage Class Specifiers)

存儲類修飾符決定了變量/函數的存儲方式和作用域。

  • auto:自動變量(局部變量),但現代C++中auto關鍵字有了新的用途,即自動類型推導。
  • register:建議編譯器盡可能將變量存儲在寄存器中(但現在很多編譯器都忽略了這個建議)。
  • static
    • 對于局部變量,static延長了變量的生命周期,但變量的作用域不變。
    • 對于全局變量和函數,static限制了它們的鏈接性(linkage),使得它們只在定義它們的文件內可見。
    • 對于類成員變量,static使得變量成為所有對象的共享變量。
  • extern:聲明變量或函數是在別的文件中定義的,或者是全局的。
  • thread_local(C++11):聲明變量的生命周期與線程相同,每個線程都擁有該變量的一個獨立實例。

3. 類型修飾符(Type Modifiers)

類型修飾符影響變量或函數的類型或特性。

  • const:表示變量或函數的返回值不可修改。
  • volatile:告訴編譯器該變量的值可能會在程序的控制之外被改變(例如,被操作系統、硬件或其他線程改變)。
  • signedunsigned:用于整數類型,指定變量是有符號還是無符號的。
  • longshort:用于整數類型,指定變量的存儲大小。
  • enum:定義枚舉類型。
  • structclass:定義復合數據類型。

4. 函數修飾符

  • const:用于成員函數,表示該函數不會修改對象的任何成員變量(如果是非靜態成員函數)。
  • noexcept(C++11):指定函數不會拋出任何異常。如果函數確實拋出了異常,程序會調用std::terminate()立即終止。
  • virtual:允許在派生類中重寫基類的成員函數。
  • override(C++11):明確指定一個成員函數是重寫了基類中的虛函數。
  • final(C++11):用于類和方法,防止類被繼承或方法被進一步重寫。

二、C++ 修飾符類型-案例

當然,下面我將提供幾個使用不同C++修飾符的案例代碼。這些案例將涵蓋訪問修飾符、存儲類修飾符、類型修飾符以及函數修飾符。

1. 訪問修飾符案例

class MyClass {
public:void publicFunction() {// 公有成員函數,可以在類外部訪問}protected:void protectedFunction() {// 保護成員函數,只能在類內部、派生類以及友元中訪問}private:void privateFunction() {// 私有成員函數,只能在類內部訪問}
};

2. 存儲類修飾符案例

#include <iostream>class MyClass {
public:static int staticVar; // 靜態成員變量,所有對象共享void printStaticVar() {std::cout << staticVar << std::endl;}
};int MyClass::staticVar = 0; // 靜態成員變量的定義int main() {MyClass obj1, obj2;obj1.staticVar = 10; // 通過任一對象修改obj2.printStaticVar(); // 輸出 10extern int globalVar; // 聲明外部變量// 假設 globalVar 在其他地方定義并初始化// register 修飾符在現代C++中通常不推薦使用,因為它對編譯器來說是建議性的// register int regVar; // 示例,但通常不推薦這樣做return 0;
}// 假設在另一個文件中定義的 globalVar
// int globalVar = 20;

3. 類型修飾符案例

#include <iostream>class MyClass {
public:void display() const { // const 成員函數,保證不修改任何成員變量std::cout << "Display function called" << std::endl;}// 使用 signed 和 unsignedvoid showIntegers() {signed int sInt = -10;unsigned int uInt = 10;std::cout << "Signed: " << sInt << ", Unsigned: " << uInt << std::endl;}
};int main() {MyClass obj;obj.display();obj.showIntegers();return 0;
}

4. 函數修飾符案例

#include <iostream>
#include <stdexcept>class MyClass {
public:virtual void virtualFunction() {// 虛函數,可以在派生類中被重寫std::cout << "Base class function" << std::endl;}void myFunction() noexcept {// noexcept 函數,保證不拋出異常// 如果嘗試拋出異常,程序將調用 std::terminate()// 注意:這里的函數體沒有實際拋出異常}void overriddenFunction() override { // 使用 override 明確指定重寫// 這里是重寫基類中的虛函數(假設基類中有相應的虛函數聲明)std::cout << "Overridden function" << std::endl;}// 注意:final 修飾符用于類和方法時,表示該類不能被繼承或該方法不能在派生類中被重寫// 這里沒有直接展示 final 的用法,因為它需要在類的繼承關系中體現
};// 假設有 MyClass 的派生類,可以展示 virtual 和 override 的用法
// class DerivedClass : public MyClass {
// public:
//     void virtualFunction() override {
//         // 重寫 MyClass 中的 virtualFunction
//         std::cout << "Derived class function" << std::endl;
//     }
// };int main() {MyClass obj;obj.virtualFunction(); // 調用基類函數obj.myFunction(); // 調用 noexcept 函數// obj.overriddenFunction(); // 如果 MyClass 中有對應的虛函數聲明,則可以這樣調用// 演示 noexcept 的異常處理(盡管這個例子沒有實際拋出異常)// try {//     throw std::runtime_error("Error");//     obj.myFunction(); // 假設 myFunction 內部有拋出異常的代碼,但由于 noexcept,這里不會執行// } catch (...) {//     std::cout << "Exception caught, but myFunction() is noexcept and should not have thrown" << std::endl;//     // 注意:如果 myFunction 實際上是 noexcept 的,并且拋出了異常,程序將不會進入這個 catch 塊//     // 相反,它將調用 std::terminate()// }
}

三、C++ 中的類型限定符

在C++中,類型限定符(Type Qualifiers)主要用于限制或改變變量的類型或行為。最常見的類型限定符包括constvolatile。這些限定符可以與基本數據類型、指針、引用等一起使用,以提供額外的信息給編譯器和開發者。

1. const 限定符

const限定符用于聲明一個變量為常量,意味著一旦該變量被初始化后,其值就不能被改變。const也可以用于修飾函數參數、返回值以及成員函數,以表明這些函數不會(或不應該)修改任何數據。

案例代碼

#include <iostream>void display(const int& value) {// 嘗試修改value會導致編譯錯誤// value = 10; // 編譯錯誤std::cout << "Value: " << value << std::endl;
}int main() {const int a = 5; // a是一個常量,其值不能被修改// a = 10; // 編譯錯誤display(a); // 傳遞a的引用,但由于是const,所以display函數內部不能修改它const int* ptr = &a; // ptr是一個指向常量的指針,不能通過ptr修改a的值// *ptr = 10; // 編譯錯誤// 但是,ptr本身是可以被修改的,指向另一個常量const int b = 20;ptr = &b; // 合法,ptr現在指向b// 指向常量的指針的常量(即,指針本身也是常量)int c = 30;const int* const cPtr = &c; // cPtr不能指向其他地址,也不能通過cPtr修改c的值// cPtr = &a; // 編譯錯誤,cPtr是常量return 0;
}

2. volatile 限定符

volatile限定符告訴編譯器該變量的值可能會以編譯器無法預見的方式被改變。這通常用于嵌入式編程、多線程編程或訪問由硬件直接修改的內存位置時。編譯器在優化代碼時會考慮變量的volatile屬性,以確保每次訪問該變量時都直接從其內存地址讀取值,而不是使用可能已存儲在寄存器中的緩存值。

案例代碼:(這個案例可能不那么直觀,因為它依賴于外部條件來改變變量的值)

#include <iostream>// 假設有一個硬件寄存器,其值可能會被外部事件(如中斷)改變
volatile int hardwareRegister = 0; // 聲明為volatile,因為值可能隨時改變void checkHardwareStatus() {// 循環檢查hardwareRegister的值,直到它變為非零(表示某種硬件事件)while (hardwareRegister == 0) {// 在這里,編譯器不會優化掉對hardwareRegister的訪問// 即使它看起來像是在一個無限循環中}// 處理硬件事件...std::cout << "Hardware event detected!" << std::endl;
}int main() {// 在實際應用中,hardwareRegister的值可能由中斷服務例程(ISR)改變// 這里我們模擬這個行為// ...(模擬代碼省略)checkHardwareStatus();return 0;
}

volatile的使用應謹慎,因為它會阻止編譯器進行某些優化,這可能會降低程序的性能。只有當確實需要時才應使用volatile

四、相關鏈接

  1. Visual Studio Code下載地址
  2. Sublime Text下載地址
  3. 「C++系列」C++簡介、應用領域
  4. 「C++系列」C++ 基本語法
  5. 「C++系列」C++ 數據類型
  6. 「C++系列」C++ 變量類型
  7. 「C++系列」C++ 變量作用域
  8. 「C++系列」C++ 常量知識點-細致講解

在這里插入圖片描述

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

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

相關文章

精講:java之多維數組的使用

一、多維數組簡介 1.為什么需要二維數組 我們看下面這個例子&#xff1f;“ 某公司2022年全年各個月份的銷售額進行登記。按月份存儲&#xff0c;可以使用一維數組。如果改寫為按季度為單位存儲怎么辦呢&#xff1f; 或許現在學習了一維數組的你只能申請四個一維數組去存儲每…

【福利】代碼公開!咸魚之王自動答題腳本

轉載請注明出處&#xff1a;小鋒學長生活大爆炸[xfxuezhagn.cn] 如果本文幫助到了你&#xff0c;歡迎[點贊、收藏、關注]哦~ 微信或QQ打開咸魚之王小程序&#xff0c;進入答題界面&#xff0c;運行main.py。期間不要動鼠標。 可自行更改代碼來適配自己的需求~ 可以按照示例圖片…

Kubernetes(k8s)和Docker Compose本質區別

Kubernetes&#xff08;k8s&#xff09;和Docker Compose是兩種不同的容器編排工具&#xff0c;它們有各自的特點和使用場景。 Kubernetes&#xff1a; Kubernetes是一個開源的容器編排平臺&#xff0c;用于自動化計算機軟件的部署、擴展和管理。它支持跨多個主機集群的容器化…

HarmonyOS Next 原生應用開發-從TS到ArkTS的適配規則(四)

一、不支持以#開頭的私有字段 規則&#xff1a;arkts-no-private-identifiers 級別&#xff1a;錯誤 ArkTS不支持使用#符號開頭聲明的私有字段。改用private關鍵字。 TypeScript class C {#foo: number 42 }ArkTS class C {private foo: number 42 }二、類型、命名空間的命…

深入了解線程鎖的使用及鎖的本質

文章目錄 線程鎖的本質局部鎖的使用 鎖的封裝及演示線程饑餓問題 線程加鎖本質可重入和線程安全死鎖問題 根據前面內容的概述, 上述我們已經知道了在linux下關于線程封裝和線程互斥,鎖的相關的概念, 下面就來介紹一下關于線程鎖的一些其他概念. 線程鎖的本質 當這個鎖是全局的…

Codeforces Round #956 (Div. 2) and ByteRace 2024

A. Array Divisibility 思路: 找出特例,發現輸出 1~&#x1d45b; 符合題意。直接輸出1~n即可. 代碼: #include<bits/stdc.h> using namespace std; typedef long long ll; #define N 1000005 ll dp[N], w[N], v[N], h[N]; ll dis[1005][1005]; ll a, b, c, n, m, t;…

iOS 開發技巧 - 使用本地 json 文件

前言 使用本地 json 文件的場景&#xff0c;在我們開發功能的階段&#xff0c;服務端接口字段定義好了后&#xff0c;有些接口響應很慢&#xff0c;請求到響應可能要 幾十秒甚至一分鐘&#xff0c;我們需要頻繁調用接口來調試功能&#xff1b;還有就是調用一些我們需要付費的三…

Ubuntu20.04下修改samba用戶密碼

Ubuntu20.04下修改samba用戶密碼 在Ubuntu系統中&#xff0c;修改samba密碼通常涉及到兩個方面&#xff1a;更改samba用戶的密碼和重置samba服務的密碼數據庫。以下是如何進行操作的步驟&#xff1a; 1、更改samba用戶密碼&#xff1a; 打開終端&#xff0c;使用以下命令更改…

vue打包terser壓縮去除控制臺打印和斷點

情況一&#xff1a; 1、vue-cli搭建 代碼壓縮工具terser在vue-cli里面是自動支持的&#xff0c;所以直接在vue.config.js里面加入下面配置&#xff1a; const {defineConfig} require(vue/cli-service) module.exportsdefineConfig({transpileDependencies:true,terser:{te…

看影視學英語(假如第一季第一集)

in the hour也代表一小時嗎&#xff1f;等同于in an hour&#xff1f;

activemq-CVE-2022-41678

Apache ActiveMQ Jolokia 后臺遠程代碼執行漏洞 Apache ActiveMQ在5.16.5&#xff0c;5.17.3版本及以前&#xff0c;后臺Jolokia存在一處任意文件寫入導致的遠程代碼執行漏洞。 啟動環境 admin/admin 方法一&#xff1a;利用poc 這個方法受到ActiveMQ版本的限制&#xff0c;因…

Linux 創建新虛擬機的全過程圖解

一、創建新虛擬機 1.選擇自定義 2.直接下一步 3.選擇稍后安裝 4.設置虛擬機名和安裝位置 5.配置處理器&#xff08;處理器數量&#xff1a;4、每個處理器的內核&#xff1a;2&#xff09; 6. 內存選擇 7.網絡類型 8. IO控制器類型-默認推薦 9.磁盤類型-默認推薦 10.選擇虛擬磁…

JS代碼動態打印404頁面源碼

JS代碼動態打印404頁面源碼&#xff0c;適合做網站錯誤頁&#xff0c;具有js動態打印效果&#xff0c;喜歡的朋友可以拿去 源碼由HTMLCSSJS組成&#xff0c;記事本打開源碼文件可以進行內容文字之類的修改&#xff0c;雙擊html文件可以本地運行效果&#xff0c;也可以上傳到服務…

Redis 7.x 系列【22】主從復制配置項

有道無術&#xff0c;術尚可求&#xff0c;有術無道&#xff0c;止于術。 本系列Redis 版本 7.2.5 源碼地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目錄 1. 前言2. 配置說明2.1 replicaof2.2 masterauth2.3 masteruser2.4 replica-serve-sta…

Linux udp編程

我最近開了幾個專欄&#xff0c;誠信互三&#xff01; > |||《算法專欄》&#xff1a;&#xff1a;刷題教程來自網站《代碼隨想錄》。||| > |||《C專欄》&#xff1a;&#xff1a;記錄我學習C的經歷&#xff0c;看完你一定會有收獲。||| > |||《Linux專欄》&#xff1…

Go中gin框架的*gin.Context參數常見實用方法

梗概&#xff1a; *gin.Context是處理HTTP請求的核心。ctx代表"context"&#xff08;上下文&#xff09;&#xff0c;它包含了處理請求所需的所有信息和方法&#xff0c;例如請求數據、響應構建器、路由參數等。 基本的格式&#xff1a; func SomeHandler(ctx *gi…

空間計量模型及 Stata 具體操作步驟

目錄 一、引言 二、空間計量模型理論原理 空間自回歸模型&#xff08;SAR&#xff09;&#xff1a; 空間誤差模型&#xff08;SEM&#xff09;&#xff1a;&#xff0c; 空間杜賓模型&#xff08;SDM&#xff09;&#xff1a; 三、實證模型構建 四、數據準備 五、Stata …

14-56 劍和詩人30 - IaC、PaC 和 OaC 在云成功中的作用

介紹 隨著各大企業在 2024 年加速采用云計算&#xff0c;基礎設施即代碼 (IaC)、策略即代碼 (PaC) 和優化即代碼 (OaC) 已成為成功實現云遷移、IT 現代化和業務轉型的關鍵功能。 讓我在云計劃的背景下全面了解這些代碼功能的當前狀態。我們將研究現代云基礎設施趨勢、IaC、Pa…

【電路筆記】-C類放大器

C類放大器 文章目錄 C類放大器1、概述2、C類放大介紹3、C類放大器的功能4、C 類放大器的效率5、C類放大器的應用:倍頻器6、總結1、概述 盡管存在差異,但我們在之前有關 A 類、B 類和 AB 類放大器的文章中已經看到,這三類放大器是線性或部分線性的,因為它們在放大過程中再現…

Collection 和 Collections 的區別與用法

Collection 和 Collections 的區別與用法 1、Collection 接口1.1 主要特點1.2 常見方法 2、 Collections 工具類2.1 主要特點2.2 常見方法 3、示例代碼3.1 使用 Collection 接口3.2 使用 Collections 工具類 4、總結 &#x1f496;The Begin&#x1f496;點點關注&#xff0c;收…