iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++中const与constexpr的区别是什么
  • 185
分享到

C++中const与constexpr的区别是什么

2023-06-21 21:06:14 185人浏览 泡泡鱼
摘要

这篇文章主要讲解了“c++中const与constexpr的区别是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++中const与constexpr的区别是什么”吧!一.const常量

这篇文章主要讲解了“c++中const与constexpr的区别是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++中const与constexpr的区别是什么”吧!

    一.const常量与#define比较

    define只是简单的替换,没有类型,const可以做到防窜改与类型安全

    而且#define会在内存中可能(有几次替换就有几次拷贝)有多份拷贝,对于字面值常量加不加const都一样,例如:const char* arr = “123”;,储存在常量区,只有一份拷贝;对于局部对象,常量存放在栈区,例如:void add(){const char crr[] = “123”;},这里“123”本应储存在栈上,但编译器可能会做某些优化,将其放入常量区;对于全局对象,常量存放在全局/静态存储区;用const会比#define使用更少的空间,效率更高。

    这里有一个小例子:char* brr = "123"; char drr[] = "123";前者字符串123存在常量区,不能通过brr去修改"123"的值;后者"123"保存在栈区,可以通过drr去修改。

    现在C++除了一些特定用法,推荐用const,inline,enum等替换宏——来自《Effective C++》条款02

    二.const修饰

    1.修饰普通变量,必须初始化

    const int a = 10; 表示int对象a,是一个常量,不可以改变值,从编译器生成二进制角度看,生成的a存放在.rodata段,也就是只读(readonly)区域。不过并不绝对,有的时间统计优化等级开的高,也不取地址,可能会优化成立即数在.text段中。

    2.修饰类变量和成员变量

    class cAAA{public:    cAAA(int a) : m_iV(a){}    const int GetValue() const {return m_iV;}    void AddValueOneTime(){m_iChangeV++;}private:    const int m_iV;public:    mutable int m_iChangeV;    static const int m_iStaticV;};static const int m_iStaticV = 1000;const cAAA aa(100);aa.GetValue();aa.m_iChangeV++;
    • cAAA类成员m_iV是const变量,必须放到初始化列表中进行初始化,不能进行赋值。

    • 对于静态常成员,与普通静态成员类似,推荐放到类外.cpp中初始化。

    • aa只能调用const函数,如aa.GetValue(),不能调用非常成员函数aa.AddValueOneTime()。

    • 对于这种const对象,又想修改成员,可以在成员声明加上mutable,这样const对象aa也可以修改m_iChangeV,这种用法比较少。

    3.修饰成员函数

    • 表示这个函数可以被const对象调用,也可以被普通对象调用,不会改变对象的成员,也就是说更像一种只读不写型的逻辑运算,所以有些人推荐类成员函数,可以都加上const。有一个小技巧,当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复;但反过来不行,const函数内部也必须只能调用const函数—— 《Effective C++》条款03

    • 有一点要注意,编译器强制实施bitwase constness,但编写程序时应该使用conceptual constness,解决编译器的bitwase constness属性就用到了上述的mutable。关于介绍bitwase constness的具体表现可以参考《Effective C++》条款03。

    4.修饰指针

    const char* p1;char const *p2;char* const p3;const char* const p4;

    对于初学者来说这大概是很难理解的一个知识点,怎么区分这四个呢?记住秘诀,直接从右向左读就一招制敌了。

    • p1是一个指针,指向char字符常量,表示p1所指对象内容不可以改,所指地址可以改。

    • p2同p1,写法不同,两者等价。

    • p3是一个常量,且是个指针,指向char字符,表示p3所指对象内容可以改,所指地址不可以改。

    • p4是一个常量,且是个指针,指向char字符常量,表示p4所指对象内容不可以改,且所指地址也不可以改。

    • 相对来说p1,p2是最常用传参或者返回值的手段。

    5.修饰引用

    修饰引用和对象差不多,对象内容不可以改变。作为函数参数传参数,不存在copy开销,这是比较推荐的写法,例如:拷贝构造函数,赋值构造,STL里用于比较的函数或者仿函数,详情请参阅《Effective C++》条款20。bool Less(const cAAA& left, const cAAA& right);

    float dValue = 1.05f;const int& a = dValue;const int iTemp = dValue;const int& a = iTemp;

    因为常引用不能改变,这种情况下编译器会创建一个临时变量来处理隐式转换,我们实际是对临时变量进行了常引用。

    三.const转换

    一般来说,从T*转换到const T*是比较简单的,且编译器支持的隐式转换,也可以显示的用模板处理,例如我们简单写一下RemoveConst模板,最后用using化名一下。但从const T*T*就麻烦一些,推荐使用const_cast。

    template <typename T>struct RemoveConst{    typedef T Type;};template <typename T>struct RemoveConst<const T>{    typedef T Type;};template <typename T>using RCType = typename RemoveConst<T>::Type;

    四.顶层const与底层const

    • 简单来说const修饰的对象本身不能改变就是顶层const,但如果是指针或者引用的对象不能改变,则称为底层const。

    • const int cV = 10; cV是顶层const,本身不能改变

    • char const *p2; p2是底层const,p2本身值可以改变,但所指内容不可以改变

    • char* const p3; p3是顶层const,p3的本身值不可以改变

    • const char* const p4; p4既是顶层const,又是底层const

    • 注:对于上述模板RCType是无法移除p2这种底层const,如果要移除,请用const_cast<T*>移除,但这种操作可能引起Crash或者未知风险

    const char* pA = "sss";char* pB = const_cast<char*>(pA);auto pC = RCType<decltype(pA)>(pA);std::cout << "type is the same: " << std::is_same<decltype(pB), decltype(pC)>::value << std::endl;std::cout << "pB Type Name: " << typeid(pB).name() << "pc Type Name: " << typeid(pC).name() << std::endl;//pB[0] = 'A';//error, Segmentation fault

    五.C++11新引入的constexpr

    这个关键字表示这是一个常量表达式,是一个编译期就可以确认的值,最常用于模板中,例如模板递归求值。

    它可不只是变量,例如:

    const int iSize1 = sizeof(int);const int iSize2 = GetSize();

    iSize1是个常量,编译期的,但iSize2就不一定,它虽然不能改变,但要到GetSize()执行结束,才能知道具体值,这与常量一般在编译期就知道的思想不符,解决这个问题的方法就是改为:constexpr int iSize2 = GetSize(); 这样要求GetSize()一定要能在编译期就算出值,下面几个例子中GetSizeError()就会编译失败。GetFibo函数,编译期就已经递归计算出值。

    constexpr int GetSize(){  return sizeof(int) + sizeof(double);}constexpr int GetSizeError(){  return random();}constexpr int GetCalc(int N){  return N <= 1 ? 1 : N * GetCalc(N - 1);}const int iSize1 = sizeof(int);constexpr int iSize2 = GetSize();//constexpr int iSize3() = GetSizeError();constexpr int iSize4 = GetCalc(10);std::cout << iSize1 << " " << iSize2 << " " << iSize4 <<std::endl;

    当然我们可以用模板写GetCalc函数:

    template <int N>struct TCalc{  static constexpr int iValue = N * TCalc<N-1>::iValue;};template <>struct TCalc<1>{  static constexpr int iValue = 1;};std::cout << TCalc<10>::iValue << std::endl;

    感谢各位的阅读,以上就是“C++中const与constexpr的区别是什么”的内容了,经过本文的学习后,相信大家对C++中const与constexpr的区别是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

    --结束END--

    本文标题: C++中const与constexpr的区别是什么

    本文链接: https://www.lsjlt.com/news/300773.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • C++中const与constexpr的区别是什么
      这篇文章主要讲解了“C++中const与constexpr的区别是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++中const与constexpr的区别是什么”吧!一.const常量...
      99+
      2023-06-21
    • 浅谈C++中const与constexpr的区别
      目录一.const常量与#define比较二.const修饰1.修饰普通变量,必须初始化2.修饰类变量和成员变量3.修饰成员函数4.修饰指针5.修饰引用三.const转换四.顶层co...
      99+
      2024-04-02
    • C++和C中const的区别是什么
      本篇内容介绍了“C++和C中const的区别是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!const,这个词字面意思为:常数。这就表示...
      99+
      2023-06-21
    • C++11的const, const expression和constexpr有什么作用
      这篇文章主要讲解了“C++11的const, const expression和constexpr有什么作用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++11的const, const...
      99+
      2023-06-19
    • 详解C++中的const和constexpr
      目录一.const常量与#define比较二.const修饰1.修饰普通变量,必须初始化2.修饰类变量和成员变量3.修饰成员函数4.修饰指针5.修饰引用三.const转换四.顶层co...
      99+
      2024-04-02
    • 怎么解析C++中的const和constexpr
      本篇文章为大家展示了怎么解析C++中的const和constexpr,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一.const常量与#define比较define只是简单的替换,没有类型,cons...
      99+
      2023-06-21
    • C语言中const和define的区别是什么
      本文小编为大家详细介绍“C语言中const和define的区别是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言中const和define的区别是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。def...
      99+
      2023-06-29
    • C# const和static readonly区别是什么
      这篇文章主要介绍“C# const和static readonly区别是什么”,在日常操作中,相信很多人在C# const和static readonly区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
      99+
      2023-06-17
    • javascript的var与let,const的区别是什么
      本篇内容主要讲解“javascript的var与let,const的区别是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript的var与let,const的区别是什么”吧!说到...
      99+
      2023-06-22
    • ES6中let、const的区别是什么
      这篇文章将为大家详细讲解有关ES6中let、const的区别是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。let和const相同点都存在块级作用域都不存在变量声明提...
      99+
      2024-04-02
    • C++中const char*、char const*、char * const三者的区别
      目录一、const char *ptr;二、char const *ptr;三、char * const ptr;C/C++ 中关于以下三种定义: const char *...
      99+
      2024-04-02
    • const在c和c++中的区别
      在 c 和 c++ 中,const 关键字用于声明常量。在 c 中,const 只能修饰变量,不能修饰指针或数组;在 c++ 中,const 可以修饰变量、指针和数组。主要的差异在于:作...
      99+
      2024-04-28
      c++ 作用域
    • es6中let和const的区别是什么
      这篇“es6中let和const的区别是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“...
      99+
      2024-04-02
    • JavaScript中var,let和const的区别是什么
      这篇文章主要为大家展示了“JavaScript中var,let和const的区别是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JavaScript中var...
      99+
      2024-04-02
    • C++和C中const的区别详解
      目录C中的constconst修饰局部变量const修饰全局变量const修饰的全局变量有外部链接属性const与指针C++中的constconst修饰普通全局变量const修饰普通...
      99+
      2024-04-02
    • var、let及const的区别是什么
      这篇文章主要介绍了var、let及const的区别是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇var、let及const的区别是什么文章都会有所收获,下面我们一起来看看吧。什么是JavaScript?首...
      99+
      2023-07-04
    • c#中monitor与mutex的区别是什么
      在C#中,Monitor和Mutex都是用来控制并发访问的机制,但它们有一些区别: Mutex是一个系统级别的同步对象,而Mon...
      99+
      2024-03-15
      c#
    • C#中Backgroundworker与Thread的区别是什么
      本篇内容介绍了“C#中Backgroundworker与Thread的区别是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.Backg...
      99+
      2023-07-02
    • c与javascript的区别是什么
      这篇文章主要介绍“c与javascript的区别是什么”,在日常操作中,相信很多人在c与javascript的区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”c与ja...
      99+
      2024-04-02
    • c#中task与thread区别是什么
      这篇文章主要介绍了c#中task与thread区别是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.什么是thread当我们提及多线程的时候会想到thread和thre...
      99+
      2023-06-29
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作