C++語言編程規范-常量

01 C++還有搞頭嗎??

02 常量??

不變的值更易于理解、跟蹤和分析,所以應該盡可能地使用常量代替變量,定義值的時候,應該把?const?作為默認的選項。

使用?const?常量取代宏

說明:宏是簡單的文本替換,在預處理階段時完成,運行報錯時直接報相應的值;跟蹤調試時也是顯示值,而不是宏名;宏沒有類型檢查,不安全;宏沒有作用域。

示例

    #define?MAX_MSISDN_LEN (20)?//不好的例子
    const?int?MAX_MSISDN_LEN =?20;?//好的例子

    03??

    一組相關的整型常量應定義為枚舉

    說明:之所以使用枚舉,基于:

    ??

    枚舉比#define?或 const int 更安全,因為編譯器會檢查參數值是否是否位于枚舉取值范圍內,從而避免錯誤發生。

    示例:

      //好的例子:
      enum?DayOfWeek{sunday,monday, tuesday, wednesday, thursday, friday, saturday}; ?
      enum?Color{black, blue, white, red, purple}; ?
      BOOL?ColorizeCalendar(DayOfWeek today, Color todaysColor); ?
      ColorizeCalendar(blue, sunday);?//編譯報錯,Blue和Sunday位置錯誤
      //不好的例子: ?
      const?int?sunday =?0; ?
      const?int?monday =?1; ?
      const?int?black =?0; ?
      const?int?blue =?1; ?
      BOOL?ColorizeCalendar(int?today,?int?todaysColor); ?
      ColorizeCalendar(blue, sunday);?//不會報錯

      ??

      當枚舉值需要對應到具體數值時,須在聲明時顯示賦值。否則不需要顯式賦值,以避免重復賦值,降低維護(增加、刪除成員)工作量。

      示例:

        //好的例子:S協議里定義的設備ID值,用于標識設備類型
        enum?TDeviceType ?
        { ?
        DEV_UNKNOWN =?-1, ?
        DEV_DSMP =?0, ?
        DEV_ISMG =?1, ?
        DEV_WAPPORTAL =?2??
        };
        //好的例子:程序中用來標識會話狀態的枚舉定義
        enum?TSessionState ?
        { ?
        SESSION_STATE_INIT, ?
        SESSION_STATE_CLOSED, ?
        SESSION_STATE_WAITING_FOR_RSP ?
        };

        ??

        應當盡量避免枚舉值重復,如必須重復也要用已定義的枚舉來修飾,例如:

          typedef enum ?
          { ?
          RTCP_SR = 200, ?
          RTCP_MIN_TYPE = RTCP_SR, //must be lowest known type ?
          RTCP_RR = 201,
          RTCP_SDES = 202, ?
          RTCP_BYE = 203, ?
          RTCP_APP = 204, ?
          RTCP_RTPFB = 205, ?
          RTCP_PSFB = 206, ?
          RTCP_XR = 207, ?
          RTCP_RSI = 208, ?
          RTCP_PUBPORTS = 209, ?
          RTCP_MAX_TYPE = RTCP_PUBPORTS //must be highest known?
          } rtcp_type_t;

          04??

          不相關的常量,即使取值一樣,也必須分別定義

          說明:一個常量只用來表示一個特定功能,即一個常量不能有多種用途。

          示例:

            //好的例子:協議A和協議B,手機號(MSISDN)的長度都是20。
            unsigned?const?int?A_MAX_MSISDN_LEN =?20;?
            unsigned?const?int?B_MAX_MSISDN_LEN =?20;?
            //或者使用不同的名字空間:
            namespace?alib?
            {?
            const?int?MAX_MSISDN_LEN =?20;?
            }?
            namespace?blib?
            {?
            const?int?MAX_MSISDN_LEN =?20;?
            }

            05??

            盡可能使用 const

            說明:

            在聲明的變量或參數前加上關鍵字 const 用于指明變量值不可被篡改。

            成員函數加上 const?限定符表明該函數不會修改類成員變量的狀態。

            使用 const 常見的場景:

            ??函數參數:傳遞引用時,如果函數不會修改傳入參數, 該形參應聲明為 const

              void printValue(const int& value) {  // 正確:不需要修改valuestd::cout << value << std::endl;// value = 10;  // 錯誤:不能修改const參數
              }
              int main() {int x = 5;const int y = 10;printValue(x);  // 可以傳遞非const變量printValue(y);  // 可以傳遞const變量printValue(42); // 可以傳遞臨時值return 0;
              }

              ??成員函數:訪問函數(如 get 函數);不修改任何數據成員的函數;未調用非 const 函數、未返回數據成員的非 const 指針或引用的函數。

                class MyClass {
                private:
                int value;
                mutable int cache;  // 即使在const函數中也可以修改
                mutable bool cacheValid;
                public:
                MyClass(int v) : value(v), cache(0), cacheValid(false) {}
                // 正確的const成員函數示例
                int getValue() const {
                return value;  // 只讀取,不修改
                }
                int getValueWithCache() const {
                if (!cacheValid) {
                cache = value * 2;  // 修改mutable成員是允許的
                cacheValid = true;
                }
                return cache;
                }
                // 錯誤示例:這個函數修改了數據成員,不能是const
                void setValue(int v) {
                value = v;
                }
                // 錯誤示例:這個函數調用了非const成員函數,不能是const
                void updateAndGetValue() const {
                setValue(10);  // 錯誤:不能在const函數中調用非const函數
                }
                // 錯誤示例:返回了非const引用,不能是const
                int& getValueRef() const {
                return value;  // 錯誤:返回了非const引用
                }
                // 正確示例:返回const引用
                const int& getValueRef() const {
                return value;  // 正確:返回const引用
                }
                };
                int main() {
                const MyClass obj(5);
                int val = obj.getValue();  // 正確:可以在const對象上調用const成員函數
                // obj.setValue(10);       // 錯誤:不能在const對象上調用非const成員函數
                return 0;
                }

                ??數據成員:如果數據成員在對象構造之后不再發生變化, 可將其定義為 const

                  class Circle {
                  private:
                  const double radius;  // 半徑在構造后不應改變
                  const double pi;      // π值恒定不變
                  double x, y;          // 位置可以改變
                  public:
                  Circle(double r, double x, double y)
                  : radius(r), pi(3.141592653589793), x(x), y(y) {
                  // 在構造函數初始化列表中初始化const成員
                  }
                  double getArea() const {
                  return pi * radius * radius;  // 可以使用const成員
                  }
                  void move(double newX, double newY) {
                  x = newX;  // 可以修改非const成員
                  y = newY;
                  }
                  // 錯誤示例:試圖修改const成員
                  void setRadius(double newRadius) {
                  // radius = newRadius;  // 錯誤:不能修改const成員
                  }
                  };
                  int main() {
                  Circle c(5.0, 0.0, 0.0);
                  double area = c.getArea();  // 正確:可以訪問const成員
                  // c.radius = 10.0;        // 錯誤:不能修改const成員
                  return 0;
                  }
                  class Circle {
                  private:
                  const double radius;  // 半徑在構造后不應改變
                  const double pi;      // π值恒定不變
                  double x, y;          // 位置可以改變
                  public:
                  Circle(double r, double x, double y)
                  : radius(r), pi(3.141592653589793), x(x), y(y) {
                  // 在構造函數初始化列表中初始化const成員
                  }
                  double getArea() const {
                  return pi * radius * radius;  // 可以使用const成員
                  }
                  void move(double newX, double newY) {
                  x = newX;  // 可以修改非const成員
                  y = newY;
                  }
                  // 錯誤示例:試圖修改const成員
                  void setRadius(double newRadius) {
                  // radius = newRadius;  // 錯誤:不能修改const成員
                  }
                  };
                  int main() {
                  Circle c(5.0, 0.0, 0.0);
                  double area = c.getArea();  // 正確:可以訪問const成員
                  // c.radius = 10.0;        // 錯誤:不能修改const成員
                  return 0;
                  }

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

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

                  相關文章

                  【CS32L015C8T6】配置單片機PWM輸出(內附完整代碼及注釋)

                  目錄 前言&#xff1a; 一、CS32L015中定時器及PWM硬件資源介紹&#xff1a; 二、以CS32L015為例配置PWM步驟&#xff1a; 三、完整代碼及注釋 四、如果這篇文章能幫助到你&#xff0c;請點個贊鼓勵一下吧ξ( ?&#xff1e;??)~ 前言&#xff1a; CS32L015 是一款內嵌 …

                  hive表不顯示列注釋column comment的問題解決

                  安裝datasophon平臺hive后&#xff0c;發現hive表的字段注釋丟失了&#xff0c;表的注釋沒問題&#xff0c;csv格式的表沒問題&#xff0c;只有parquet和orc的表有這個問題。查網上似乎沒有這方面的問題。查看mysql表里面的中文注釋也一切正常&#xff0c;后來經過多次研究才發…

                  【筆記】AI Agent發展趨勢

                  前言 本章主要探討了現在AI技術的發展趨勢、大模型的一些局限性和小模型存在的必要性,然后引出了AI Agent的優勢與發展趨勢。 目標 學完本課程后,您將能夠: 了解大模型的局限性; 了解小模型存在的必要性; 了解AI Agent的優勢; 了解模型協同的技術。 目錄 1.AI發…

                  ChatDOC工具測評:AI驅動PDF/Word文檔處理,支持敏感內容隱私保護與表格提取分析

                  之前跟你們聊過用 Python 處理數據的 Pandas&#xff0c;今天換個更貼近日常辦公的方向 —— 給你們安利一個 AI 文檔處理工具「ChatDOC」&#xff0c;官網地址是https://www.chatdoc.com/&#xff0c;它能直接讀取 PDF、Word 里的內容&#xff0c;你不用逐頁翻文檔找信息&…

                  Vue + fetchEventSource 使用 AbortController 遇到的“只能中止一次”問題解析與解決方案

                  前言 在前端項目中&#xff0c;使用 SSE&#xff08;Server-Sent Events&#xff09; 長連接去獲取實時消息已經很常見了。像 fetchEventSource 這種封裝好的工具&#xff0c;可以幫助我們輕松處理流式請求。 不過在實踐中&#xff0c;我遇到了一個奇怪的問題&#xff1a;點擊按…

                  Django get_or_create 方法詳解

                  get_or_create 是 Django ORM 中的一個非常常用的方法&#xff0c;它用于獲取數據庫中的一個對象&#xff0c;如果該對象不存在&#xff0c;則創建一個新的對象并返回。 方法簽名&#xff1a; Model.objects.get_or_create(defaultsNone, **kwargs)參數解釋&#xff1a; defaul…

                  LangChain 文檔問答系統中高級文本分割技術

                  告別語義斷裂:LangChain 文檔問答系統中高級文本分割技術深度指南 文章目錄 引言:問題的根源——為何精準的文本分割是 RAG 系統的命脈? 第一部分:探本溯源——剖析 LangChain 默認分割器的“機械之困” 機制解析:語法驅動的“暴力”切分 問題場景化展示:語義、上下文與結…

                  Web2 vs Web3--差異一看就懂

                  互聯網技術的浪潮不斷推動著我們從Web2時代向Web3時代邁進。這兩個時代在技術架構、用戶體驗、數據所有權等方面有著顯著的差異。本文將為您詳細解析Web2與Web3之間的差異&#xff0c;并探討它們如何塑造我們的數字生活。 定義 Web2&#xff0c;即第二代互聯網&#xff0c;以其…

                  深入解析MongoDB內部架構設計

                  MongoDB內部構造詳解 MongoDB作為一款流行的NoSQL數據庫&#xff0c;其內部構造設計獨特且高效。以下從多個維度詳細解析MongoDB的內部架構和核心組件。 一、整體架構 MongoDB采用分布式架構設計&#xff0c;主要包含以下核心組件&#xff1a;應用層&#xff1a;應用程序通過語…

                  ubuntu12.04安裝opencalib手動標定并使用自己的數據

                  ubuntu22.04安裝opencalib手動標定并使用自己的數據 一、OpenCalib的部署使用 1、基本信息 官網鏈接: https://github.com/PJLab-ADG/SensorsCalibration/tree/v0.2 (官網下載的zip文件是有問題的,不建議到官網下載) 參考鏈接: https://blog.csdn.net/qq_49959714/arti…

                  scss 轉為原子css unocss

                  文章目錄前言&#x1f3af; **方案一&#xff1a;混合模式 (推薦)**&#x1f3af; **方案二&#xff1a;語義化組件類**&#x1f3af; **方案三&#xff1a;CSS 模塊化**&#x1f3af; **方案四&#xff1a;BEM 命名規范**&#x1f4a1; **推薦做法**前言 記錄讓c4 從scss 轉為…

                  【面試題】生成式排序了解嗎?

                  生成式排序是搜索排序的前沿方向&#xff0c;核心思想是利用生成式模型的能力來改善排序效果。 技術實現方式&#xff1a;序列到序列重排序 將候選文檔列表作為輸入序列使用encoder-decoder模型生成重排后的文檔序列優勢&#xff1a;能捕捉文檔間的全局相關性生成式特征提取 使…

                  【系統架構設計(15)】軟件架構設計一:軟件架構概念與基于架構的軟件開發

                  文章目錄一、核心思想二、軟件架構概念&#xff1a;系統設計的高級抽象三、軟件架構設計與生命周期&#xff1a;架構在開發流程中的演進四、架構描述語言ADL&#xff1a;架構的標準化表達五、41視圖&#xff1a;多角度的架構展現六、基于架構的軟件開發概念&#xff1a;架構驅動…

                  文件系統-哈希結構文件

                  一、核心思想哈希文件的核心思想非常簡單直接&#xff1a;通過一個計算&#xff08;哈希函數&#xff09;&#xff0c;將記錄的鍵&#xff08;Key&#xff09;直接轉換為該記錄在磁盤上的物理地址&#xff08;通常是塊地址&#xff09;&#xff0c;從而實現對記錄的快速存取。它…

                  一文吃透 C#中異步編程Task

                  一文吃透 C#中異步編程Task 一、Task 是什么 二、推薦使用場景 三、Demo:Task 的核心用法 1. 最常用的啟動方式Task.Run 2. task完成狀態與結果獲取 3. 多個任務怎么等?Wait/WaitAll/WaitAny 4. 任務想中途停掉?取消與異常處理 四、必備 API 速查表 五、避坑指南、注意事項 …

                  TDengine TIMETRUNCATE 函數用戶使用手冊

                  TDengine TIMETRUNCATE 函數用戶使用手冊 函數概述 TIMETRUNCATE 是 TDengine 中的一個時間處理標量函數&#xff0c;用于將時間戳按照指定的時間單位進行截斷操作。該函數在時間數據聚合、分組和統計分析中非常有用&#xff0c;特別適用于智能電表等時序數據的分析場景。 語法…

                  KSZ8081寄存器介紹

                  一、寄存器概覽KSZ8081MNX/RNB 支持 IEEE 802.3 標準的 MII 管理接口&#xff08;MDIO&#xff09;&#xff0c;寄存器地址范圍為 0x00 - 0x1F&#xff0c;其中寄存器 0x00 - 0x08 為 IEEE 標準寄存器&#xff0c;0x09 - 0x1F 為擴展功能寄存器。寄存器按功能可分為基本控制與狀…

                  力扣190:顛倒二進制位

                  力扣190:顛倒二進制位題目思路代碼題目 顛倒給定的 32 位無符號整數number的二進制位。 思路 思路很簡單&#xff0c;我們只需要得到number從低位到高位的每一個二進制位再把二進制位移到顛倒的res的對應二進制位即可&#xff0c;例如number的最低位為1那么res的最高位即1&a…

                  鴻蒙NEXT交互機制解析:從輸入設備到手勢響應的全面指南

                  深入探索鴻蒙NEXT的交互設計&#xff0c;掌握下一代人機交互核心技術在智能設備無處不在的今天&#xff0c;一個操作系統的交互設計質量直接影響著用戶體驗。鴻蒙NEXT作為華為推出的新一代操作系統&#xff0c;在交互設計上帶來了許多創新和突破。本文將全面解析鴻蒙NEXT的交互…

                  通過IDEA寫一個服務端和一個客戶端之間的交互

                  服務端代碼&#xff1a;WebSocketConfig代碼package org.example.hufamessagedemo;import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.*;Configuration EnableWebSocket public class WebSocketConfig i…