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

const 与 constexpr

一、问题:

遇到过该问题:在类中,与static关键字一起使用时, 未在类外进行再次声明,导致编译报错

class A
{public:void txMsg(const int& x) const;void rxMsg(const int x);void func();private:static const int  m_data1 = 10; static constexpr int m_data2 = 20;static inline const int m_data3 = 30; 
};// 正确做法, 类外进行再次声明
const int A::m_data1; 
constexpr int A::m_data2; A::func()
{this->txMsg(m_data1); this->rxMsg(m_data1);this->txMsg(m_data2); this->rxMsg(m_data2);this->txMsg(m_data3); this->rxMsg(m_data3);
}//错误做法, 未进行再次声明A::func()
{this->txMsg(m_data1);       // 编译报错this->rxMsg(m_data1);this->txMsg(m_data2);       // 编译报错this->rxMsg(m_data2);this->txMsg(m_data3); this->rxMsg(m_data3);
}

原因就在于static关键字上,单一定义原则(ODR),当静态成员变量需要取地址时,必须在类外进行再次声明,否则编译器会报错。

类型类内初始化是否需要类外再次声明
static const int可以如果要被取地址,需要
static const 非整型不可以需要
static constexpr 任意类型可以如果要被取地址,需要
static inline const 任意类型可以不需要

二、 const 与 constexpr的区别

回顾下内存区域:

内存区域存储内容生命周期管理对象
代码区存放函数体的二进制代码程序运行期间操作系统
全局区存放全局变量和静态变量以及常量程序运行期间操作系统
栈区存放函数的参数值,局部变量函数运行期间编译器自动分配释放
堆区存放new,malloc分配的内存数据程序运行期间程序员手动释放,否则由操作系统回收

  • const:可以修饰多种变量,包括局部变量、全局变量、静态变量等;因此const变量的内存区域取决于它定义的位置

    • 局部变量:栈区
    void func()
    {// 局部变量,栈区const int local_var = 10;
    }
    
    • 局部变量:堆区
    void func()
    {// 堆区const int* heap_var = new const int(10);delete heap_var;
    }
    
    • 全局变量:全局区
const int global_var = 10; // 全局区
  • 静态变量:全局区
class A
{private:static const int static_var = 10; // 全局区
};// 需要在类外初始化,否则编译器会报错,尤其是函数引用到该值时
const int A::static_var = 10; // 全局区
  • constexpr: 是 编译期常量(还包含表达式),必须在编译期就能计算出来;但它可能会被编译期给优化成一个立即数(取决于编译器)
    • 全局变量:可能只在编译期存在
    constexpr int global_var = 10; 
    
    • 局部变量:可能被编译器优化成一个立即数
    void func()
    {constexpr int local_expr = 100;int array[local_expr]; 
    }
    
  • 常见场景:
    1. 对数组进行初始化:
    int main()
    {const int arr_size = 10;int arr[arr_size];        // 报错,因为arr_size在编译期无法确定// 如果想要const修饰的变量通过,那么得让它分配得内存,在编译期就能通过constexpr int arr_size_expr = 10;int arr[arr_size_expr]; // 正确return 0;
    }
    
    1. switch的case标签:
    const int red = 1;switch(color){case red:     //  报错,因为red在编译期无法确定//  即便加上 sattic关键字,也不行case 1:       //  正确// ...
    }constexpr int red_expr = 1;
    switch(color){case red_expr: // 正确// ...
    }
    
    1. 替换宏定义:
    #define squre(x) { return x * x; }    //不推荐constexpr int squre_expr(int x) { return x * x; } // 推荐
    float array[squre_expr(3)]; // 正确
    

三、小结:

  • constexpr是C++11引入的,用于定义编译期常量。它不仅可以修饰变量,还可以修饰表达式,并且要求该表达式在编译时就能计算出来。相比之下,const关键字主要用于修饰变量,并且在运行时也可能存在(取决于变量的存储位置)。
  • 大部分场景推荐使用constexpr,因为它提供了更严格的约束和更好的性能。
http://www.dtcms.com/a/500333.html

相关文章:

  • 网站的推广运营模板图片可爱
  • 科技软件公司网站模板下载做网站需要前置审批
  • Spring远程命令执行漏洞复现:原理分析+环境搭建+渗透实践(CVE-2018-1270)
  • 杭州城市建设网站wordpress注册白屏
  • python进阶题4
  • 沈阳设计网站公司网站网站建设服务目标
  • 郑州上市企业网站建设uniapp跳转内部页面
  • sm2025 模拟赛23 (2025.10.18)
  • 永泰城乡建设网站有哪些网站使用ftp
  • 力扣 547. 省份数量
  • 网站设计用于制作网页的工具软件
  • 长沙官网网站制作公司梅江区建设局网站
  • 国外的电商网站有哪些方面雪军miui一键优化
  • DAY40训练和测试的规范写法
  • 大麦抢票脚本技术解析
  • python:requests+beautifulSoup
  • 网站广东省备案系统设计之家官网首页
  • 建设银行悦生活网站小程序api接口怎么对接
  • Win11安装 Ubuntu 22.04 子系统 - WSL2 - 安装完迁移到其它盘
  • 锂电池保护芯片的船运模式
  • Foundation 折叠列表
  • 卫浴建材网站建设建站seo推广
  • 青岛网站建设兼职做企业网站有什么工作内容
  • 连云港网站建设优化百度站长平台清退
  • Orleans 流系统握手机制详解
  • 视觉网络网站辽宁鞍山网站建设
  • 最新项目贺州seo
  • 飞手通航内蒙古基地落子锡林郭勒 携手疆空科技激活北疆低空经济
  • 品牌宝免费网站手机网站策划
  • 宣传网站制作泰安哪里可以做网站