1、用const修饰函数的参数

  1. 参数是值传递

    由于函数将自动产生临时变量复制该参数,该参数无需保护,没必要用const

  2. 参数是指针传递或者引用传递

    const修饰的指针或引用所指向的值不可变。如果该参数只是起“被读取”的作用,最好用const修饰保护。

对于复合数据类型,最好使用引用传递,因为值传递的过程中要进行临时对象的构造,复制,析构,这些都会造成时间和空间的浪费。

class list {
string name;
public:
void show(const list& l) {
cout << name;
}
}

2、用const修饰函数的返回值

如果函数的返回值用const修饰,接受这个返回值的变量也只能用const修饰。

const int sum(int a, int b) {return a+b;}

int s = sum(1,1); //error
const s = sum(1,1); //编译通过

3、const 成员函数

任何不会修改数据成员的函数都应该声明为const 类型。如果在编写const 成员函数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将指出错误,这无疑会提高程序的健壮性。

class list {
string name;
public:
void show(list& l) const {
cout << name;
}
}

4 、const对象

const修饰的对象只能访问const函数和const成员变量

class list {
string name;
public:
void show(list& l) const {
cout << name;
}
void show2(list& l) {
cout << name;
}
} const list l;
l.show2(); //error
l.show(); //编译通过

const 对象只在当前文件有效,例如a.cc中定义:const int MAX = 999;,这时在b.cc中声明:extern const int MAX;,编译链接后会显示undefined reference to 'MAX'。解决办法是定义前边也加上extern

5 、与constexpr区别

  1. 对于修饰Object来说

    • const并未区分出编译期常量(编译时就可以确定的常量表达式)和运行期常量
    • constexpr限定在编译期常量,也就是说,编译器看见constexpr就可以在编译期计算,所以应该尽量将一个变量声明为constexpre
  2. 对于修饰函数来说

    • constexpr修饰的函数,返回值不一定是编译期常量

      #include <iostream>
      #include <array>
      using namespace std; constexpr int foo(int i)
      {
      return i + 5;
      } int main()
      {
      int i = 10;
      std::array<int, foo(5)> arr; // OK foo(i); // Call is Ok // But...
      std::array<int, foo(i)> arr1; // Error }

所以,对于constexpr需要两方面看待。

constexpr修饰的函数,简单的来说,如果其传入的参数可以在编译时期计算出来,那么这个函数就会产生编译时期的值。但是,传入的参数如果不能在编译时期计算出来,那么constexpr修饰的函数就和普通函数一样了。不过,我们不必因此而写两个版本,所以如果函数体适用于constexpr函数的条件,可以尽量加上constexpr

而检测constexpr函数是否产生编译时期值的方法很简单,就是利用std::array需要编译期常值才能编译通过的小技巧。这样的话,即可检测你所写的函数是否真的产生编译期常值了。

6、指向常量的指针(pointer to const)、常量指针指针(const pointer) 与 constexpr指针

  • 指向常量的指针,又叫底层指针

    • 作用:不能通过指针修改值,无论指向的值是否是const, 指针本身可以改变指向。

      int a =1;
      const int b = 1;
      const int* p;
      p = &a;
      *p = 2;//错误
      p = &b;
      *p = 2; //错误
  • 常量指针,又叫顶层指针

    • 作用:不能修改指针的指向,指针本身是常量,所以必须在声明时初始化。

      int a = 1;
      int b = 1;
      int* const p = &a;
      p = &b; //报错
  • constexpr指针

    • 作用和常量指针(顶层指针)一样

注意!类型别名与常量指针

typedef int* ip;
int a = 1;
const ip p; //不能理解成 const int *p! 他等价于 int* const p; 也就是顶层指针,顶层指针必须初始化,所以这句是会报错的
const ip p = &a; //正确

7、const引用

int const& a;const int& a; 作用一样,可以不加区分。

参考:https://www.zhihu.com/question/35614219/answer/63798713

https://www.jianshu.com/p/34a2a79ea947

《C++ primer》2.4节

const用法及与constexpr区别总结的更多相关文章

  1. 【转】话说C语言const用法

    原文:话说C语言const用法 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修 ...

  2. const 用法全面总结

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...

  3. const用法详解(转)

    http://www.cnblogs.com/StudyRush/archive/2010/10/06/1844690.html 面向对象是C++的重要特性. 但是c++在c的基础上新增加的几点优化也 ...

  4. const 在C++中的区别

    一.Const作用    如下表所示: No. 作用 说明 参考代码 1 可以定义const常量 const int Max = 100; 2 便于进行类型检查 const常量有数据类型,而宏常量没有 ...

  5. JavaScript中const、var和let区别浅析

    在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始 ...

  6. c++ const用法小结

    const用法 1,定义全局变量的内存分配问题 #define  Pi_1  3.14       //使用#define宏 const double Pi_2 = 3.14    //使用const ...

  7. 实例讲述PHP面向对象的特性;;;php中const与define的使用区别

    php中const与define的使用区别 1.const:类成员变量定义,一旦定义且不能改变其值. define:定义全局常量,在任何地方都可以访问.2.define:不能在类中定义,而const可 ...

  8. const用法

    一.const作用 二.const用法 1.修饰一般常量   修饰符const可以用在类型说明符前,也可以用在类型说明符后. 例如: ; ; 2.修饰常数组  修饰符const可以用在类型说明符前,也 ...

  9. 浅谈HTTP中GET、POST用法以及它们的区别

    浅谈HTTP中GET.POST用法以及它们的区别 HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符.我们可以这样认为: 一 ...

  10. static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符

    一.static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝  C++ Code  1 2 3 4 5 6 7 8 9 10 11 ...

随机推荐

  1. 错误:基于tensorflow识别mnist数据集出现ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[10000,32,28,28] and type float on

    错误:最近,在尝试运行我以前博客代码的时候出现了如下错误 2020-04-03 10:53:22.982491: W tensorflow/core/common_runtime/bfc_alloca ...

  2. 文心一言 VS 讯飞星火 VS chatgpt (194)-- 算法导论14.3 2题

    二.用go语言,改写 INTERVAL-SEARCH 的代码,使得当所有区间都是开区间时,它也能正确地工作. 文心一言,代码正常运行: 在Go语言中,处理开区间(open intervals)时,我们 ...

  3. 今天才知道 Ping 命令的意义

    当ping一个域名的时候  可以知道这个域名的解析情况,也可以知道 当前电脑是否联通了 域名. 可以看到 diandaxia.com 的域名解析是 112.124.182.113 ,而www.dian ...

  4. JS 这一次彻底理解冒泡排序

    壹 ❀ 引 在面试环节中,算法总是逃不掉的一关,对于我这种非班科出生且大学不接触数学的人来说,逻辑思维方面确实较为欠缺,昨晚跟百度的同学聊到凌晨,自我感觉差距较大,受了不小打击,所以决心抓一抓算法,做 ...

  5. 基于OpenTelemetry实现Java微服务调用链跟踪

    本文分享自华为云社区<基于OpenTelemetry实现Java微服务调用链跟踪>,作者: 可以交个朋友. 一 背景 随着业务的发展,所有的系统都会走向微服务化体系,微服务进行拆分后,服务 ...

  6. low-code 低代码平台 java 代码自动一键生成工具

    low-code low-code 是一款为 java 打造的低代码平台. 开源地址:https://github.com/houbb/low-code 特性 支持基本的增删改查 支持枚举值处理 支持 ...

  7. 【framework】应用进程启动流程

    1 前言 Activity启动流程 中介绍了从点击桌面上应用快捷方式到 Activity 的 onCreate() 方法调用流程,本将介绍应用进程的启动流程.由于应用进程启动流程复杂,本文按进程将其拆 ...

  8. springboot项目使用外置tomcat7部署项目

    Springboot使用外置tomcat7部署运行 1.pom修改 2.tomcat底下config下catalina.properties 3.在tomcat的lib文件夹下添加 javax.el- ...

  9. win32 - 使用GDI+从资源中获取图像并加载

    很多时候我们习惯使用GDI+中Image类来加载本地文件,但是有时候我们需要资源中从加载png格式的图片时,却无法使用该类. 我们可以使用FindResource,LoadResource和LockR ...

  10. 反射,装饰器,类当中的方法,property---day24

    1.反射 # ### 反射(针对于类对象 模块) '''概念:通过字符串去操作类对象或者模块当中的成员(属性方法)''' class Man(): pass class Woman(): pass c ...