本文主要介绍const修饰符在C++中的主要用法,下面会从两个方面进行介绍:类定义中使用const非类定义中使用const

1. 非类定义中使用const

非类定义中使用const是指:在除了类定义以外的场景中使用const。

1.1 变量
const int a = 1;  //定义一个常量,不可以修改
int b = 2; //定义一个普通变量,可以修改
const int &b = a; //定义一个常量引用,不可以通过引用b修改a,底层const
const int *p = &a; //定义一个普通变量,p可以修改,但是不可以通过p修改所指向的对象a,底层const
int * const q = &b; //定义一个常量指针,q不可以修改,但是可以通过q修改所指向的对象b,顶层const
const int * const s = &a; //定义一个常量指针,s不可以修改,同时不可以通过s修改所指向的对象a,靠右的是顶层const,靠左的是底层const

顶层const:变量本身是个常量

底层const:变量所指向的对象是个常量

用于声明引用的const都是底层const

1.2 函数
int fun1(const int a);  //定义一个常量形参
const int fun2(int a); //等同于'int fun1(const int a);'因为函数返回的是返回值的副本
const int& fun3(int &a); //返回常量引用,不会进行对象的拷贝(注意:不要返回局部对象的引用或者指针)
const int& fun4(int a); //这实际上是一种错误的声明方式,该函数可能会返回局部对象的引用或者指针

Tips:

  1. 引用只是一个变量的别名不是对象,因此引用不会占用存储空间
  2. 调用一个返回引用的函数得到左值,其他返回类型得到右值

2. 类定义中使用const

2.1 类成员
class Test{
public:
Test():a(10){}
void display();
private:
const int a;
};
  1. 类定义中不能进行初始化,因为在头文件中定义只是一个声明,并没有分配真正空间,因此变量是不存在的,因此是不能赋值的。
  2. 在类定义外部,const定义的变量是不能被赋值

问题:

类定义中不能赋值,类定义外部也不能赋值,但是又必须赋值,这可如何是好?

解决方案:

  1. 在构造函数后的参数初始化列表中初始化
  2. 将const变量同时声明为 static 类型进行初始化
class Test{
public:
Test():a(10){}
void display();
private:
const int a;
//static const int a;
};
//const int Test::a = 5;
2.2 类成员函数
class Test{
public:
//下面是display函数的两个重载版本
void display(); //一个普通成员函
void display() const; //一个const成员函数。
private:
const int a;
};

Tips:

成员函数都有一个额外的隐式参数this,this的值是调用该函数的对象地址,因此this是一个指针

普通成员函数的this指针类型是:Test* const this

const成员函数的this指针类型是:const Test* const this

Test t1;
const Test t2;
t1.display(); //调用void display()
t2.display(); //调用void display() const

因为两个函数的this指针类型不同,所以display有两个重载函数。

作用:

为了在函数体内禁止修改对象,可以通过定义const成员函数来实现。

Others:

下图是截自C++ primer中的片段,请重点关注两个display函数的返回值:

display 普通成员函数的返回值是:普通引用

display const成员函数的返回值是:常量引用

造成返回值不同的原因就是:this指针类型不同

3. 参考资料

  1. C++ primer 第五版-P57、P201、P231、P247
  2. C++ non-const lvalue reference cannot bind to a temporary

C++ const用法,看这一篇就够了!的更多相关文章

  1. Java中的多线程=你只要看这一篇就够了

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  2. 关于 Docker 镜像的操作,看完这篇就够啦 !(下)

    紧接着上篇<关于 Docker 镜像的操作,看完这篇就够啦 !(上)>,奉上下篇 !!! 镜像作为 Docker 三大核心概念中最重要的一个关键词,它有很多操作,是您想学习容器技术不得不掌 ...

  3. JVM内存模型你只要看这一篇就够了

    JVM内存模型你只要看这一篇就够了 我是一只孤傲的鱼鹰 让我们不厌其烦的从内存模型开始说起:作为一般人需要了解到的,JVM的内存区域可以被分为:线程栈,堆,静态方法区(实际上还有更多功能的区域,并且这 ...

  4. 【java编程】ServiceLoader使用看这一篇就够了

    转载:https://www.jianshu.com/p/7601ba434ff4 想必大家多多少少听过spi,具体的解释我就不多说了.但是它具体是怎么实现的呢?它的原理是什么呢?下面我就围绕这两个问 ...

  5. [转帖]nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件

    nginx学习,看这一篇就够了:下载.安装.使用:正向代理.反向代理.负载均衡.常用命令和配置文件 2019-10-09 15:53:47 冯insist 阅读数 7285 文章标签: nginx学习 ...

  6. 2019-5-25-win10-uwp-win2d-入门-看这一篇就够了

    title author date CreateTime categories win10 uwp win2d 入门 看这一篇就够了 lindexi 2019-5-25 20:0:52 +0800 2 ...

  7. 鸿蒙应用程序Ability(能力)看这一篇就够

    本节概述 什么是Ability Ability分类 Ability生命周期 Ability之间跳转 什么是Ability Ability意为能力,是HarmonyOS应用程序提供的抽象功能.在Andr ...

  8. windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看

    windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看 1. 新建excel表格 A B C D E 姓 名 全名 登录名 密码 李 四 李四 李四 test123!@ ...

  9. 什么是 DevOps?看这一篇就够了!

    本文作者:Daniel Hu 个人主页:https://www.danielhu.cn/ 目录 一.前因 二.记忆 三.他们说-- 3.1.Atlassian 回答"什么是 DevOps?& ...

  10. python面试看这一篇就够了

    python-面试通关宝典 有面Python开发方向的,看这一个repo就够啦? 语言特性 1.谈谈对 Python 和其他语言的区别 Python属于解释型语言,当程序运行时,是一行一行的解释,并运 ...

随机推荐

  1. KVC解析

    •  阅读  valueForKey (总体规划,先找相关方法,再找相关变量) 1.先是找相关方法,如果方法找不到 2.那么去判断 1 2 3 + (BOOL)accessInstanceVariab ...

  2. 第19届亚太零售商大会 | 奇点云CEO行在受邀出席发表演讲

    2019年9月5日—7日,第19届亚太零售商大会在重庆举行. 亚太零售商大会作为世界三大零售盛会之一,是亚太地区零售行业最具规模.最具影响力的零售行业盛会.本次大会以“新零售·新消费·新动力·合作与共 ...

  3. HDU-2544-最短路(各种最短路径算法)

    迪杰斯特拉算法--O(n^2) #include"iostream" #include"cstring" #include"cstdio" ...

  4. bat连接映射盘

    net use h: \\IP地址\目录 "密码" /user:"用户名"

  5. java String、StringBuilder

    Java中的String和StringBuilder类: 1.String对象是不可变的.每一个看起来修改了String值的方法,实际上都是创建了全新的String对象.代码示例如下: String ...

  6. Nginx 原理和架构

    Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器.Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名Nginx 里 ...

  7. git pull 显示的冲突---解决办法git stash

    git pull:显示本地仓库与远程仓库有冲突 Please, commit your changes or stash them before you can merge. Aborting 解决办 ...

  8. Spring中的事件处理

    文章目录 Spring中的事件处理 Spring 的核心是 ApplicationContext,它负责管理 beans 的完整生命周期.当加载 beans 时,ApplicationContext ...

  9. 杀入红海市场 ZUK手机底气在哪?

       从越来越奢华的发布会舞台屏幕,到创意越来越烧脑的邀请函,一款新手机的发布工作变得越来越系统化.何时展示.如何亮相,都成为影响一部手机情怀,甚至销售好坏的重要因素.虽然很难以一个固定标准衡量各个手 ...

  10. process.env

    官方: process.env属性返回一个包含用户环境信息的对象.