当前位置: 首页 > 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://www.xdnf.cn/news/1455517.html

                  相关文章:

                • 既“强悍”又“灵活”,部署在用户身边,将直播延迟压缩至毫秒级
                • Kafka 学习教程:从基础概念到实践操作
                • 分析流程自动优化!Fabarta个人专属智能体「数据分析」新功能介绍
                • 打工人日报#20250904
                • docker中的mysql变更宿主机映射端口
                • 以StarRocks为例讲解MPP架构和列式存储
                • vscode launch.json 中使用 cmake tools 扩展的命令获取可执行文件目标文件名
                • 设计师的私有化远程协作解决方案,是OpenUI与cpolar组合的标配功能
                • 目标检测系列-Yolov5下载及运行
                • 深度学习下的单阶段通用目标检测算法研究综述2.0
                • Java全栈工程师的实战面试:从Vue到Spring Boot的技术旅程
                • PSU电源原理
                • 双指针扫描使用简述
                • 【AI论文】面向大语言模型(LLMs)的具身强化学习全景图:一项调研综述
                • 新闻稿的发布平台有哪些?选对渠道让发稿效果事半功倍!
                • 移远EC200A OpenCPU笔记
                • 一文吃透同态滤波算法!从原理到 MATLAB 实战,小白也能懂
                • 解析PE文件的导入表和导出表
                • 准确率可达99%!注意力机制+UNet,A会轻松收割!
                • 20250904的学习笔记
                • HTML + CSS 创建图片倒影的 5 种方法
                • 大数据毕业设计选题推荐-基于大数据的儿童出生体重和妊娠期数据可视化分析系统-Hadoop-Spark-数据可视化-BigData
                • 加密货币武器化:恶意npm包利用以太坊智能合约实现隐蔽通信
                • 性能堪比claude sonnet4,免费无限使用!claude code+魔搭GLM4.5在ubuntu上安装完整流程
                • Cadence OrCAD Capture绘制复用管脚封装的方法图文教程
                • 蔚来8月狂卖3.1万辆,反超理想引热议!
                • C++ opencv+gstreamer编译,C++ opencv4.5.5+gstreamer1.0 -1.24.12 编译 ,cmake 4.0.0
                • OpenCV: Mat存储方式全解析-单通道、多通道内存布局详解
                • 0904网络设备配置与管理第二次授课讲义
                • 如何用仓库路线完成一个音视频实战项目:FFmpeg + SDL 简易播放器