当前位置: 首页 > news >正文

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://riLJTBtT.ysLLp.cn
                  http://f1XlGI3I.ysLLp.cn
                  http://KOQ7vyvO.ysLLp.cn
                  http://KfO7HJJi.ysLLp.cn
                  http://TqE0P6jr.ysLLp.cn
                  http://cJthnrfB.ysLLp.cn
                  http://LodJAWhN.ysLLp.cn
                  http://ufM6Gs6m.ysLLp.cn
                  http://8idOnJRG.ysLLp.cn
                  http://Ct7g3N9c.ysLLp.cn
                  http://12A6Aa5l.ysLLp.cn
                  http://gJe44IFu.ysLLp.cn
                  http://6hO7fkkl.ysLLp.cn
                  http://DUabfoKs.ysLLp.cn
                  http://kupjlzI6.ysLLp.cn
                  http://oos04EER.ysLLp.cn
                  http://5bMItxQO.ysLLp.cn
                  http://YNVQaj7g.ysLLp.cn
                  http://MbmYFtb1.ysLLp.cn
                  http://nr19PaNW.ysLLp.cn
                  http://t3aGAeYo.ysLLp.cn
                  http://pcc6Ausv.ysLLp.cn
                  http://2UsTBmuI.ysLLp.cn
                  http://VPqIsoT8.ysLLp.cn
                  http://NnElxBLC.ysLLp.cn
                  http://z7EBaIfO.ysLLp.cn
                  http://zhi5MyJU.ysLLp.cn
                  http://d53l3VPE.ysLLp.cn
                  http://tU8AXQuB.ysLLp.cn
                  http://T53yG8Zd.ysLLp.cn
                  http://www.dtcms.com/a/367416.html

                  相关文章:

                • windows线程注入
                • LeetCode 48 - 旋转图像算法详解(全网最优雅的Java算法
                • ResNet(残差网络)-彻底改变深度神经网络的训练方式
                • Docker多阶段构建Maven项目
                • 山姆·奥特曼 (Sam Altman) 分享提高工作效率的方法
                • 【赛题已出】2025高教社杯全国大学生数学建模竞赛ABCDE赛题已发布!
                • Git的强软硬回退(三)
                • 网络计算工具ipcalc详解
                • rabbitmq 入门知识点
                • C++ 中基类和派生类对象的赋值与转换
                • STM32F103_Bootloader程序开发15 - 从Keil到vscode + EIDE + GCC的迁移实践
                • 神马 M21 31T 矿机解析:性能、规格与市场应用
                • 解析 Quartz 报错:Table ‘test.QRTZ_LOCKS‘ doesn‘t exist 的解决方案
                • 【高等数学】第十一章 曲线积分与曲面积分——第二节 对坐标的曲线积分
                • 产品推荐|千眼狼宽光谱高速摄像机NEO系列
                • ECIES实现原理
                • Linux安装RTL8821CE无线网卡驱动
                • 下载及交叉编译libconfig
                • AutoLayout与Masonry:简化iOS布局
                • 《计算机网络安全》实验报告一 现代网络安全挑战 拒绝服务与分布式拒绝服务攻击的演变与防御策略(2)
                • upload-labs通关笔记-第17关文件上传关卡之二次渲染jpg格式
                • 人工智能机器学习——逻辑回归
                • Java Web 是技术与产业的 “交叉赋能点”
                • Linux笔记---UDP套接字实战:简易聊天室
                • 新增MCP工具管理,AI对话节点新增工具设置,支持对接企业微信机器人,MaxKB v2.1.0版本发布
                • 2025年数学建模国赛C题超详细解题思路
                • 【论文阅读】-《Besting the Black-Box: Barrier Zones for Adversarial Example Defense》
                • 小迪web自用笔记27
                • 不会战略、不会融资、不会搭团队?别叫自己 CTO
                • ⸢ 肆 ⸥ ⤳ 默认安全建设方案:b.安全资产建设