本文主要介绍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. 关于Apache Commons-IO的使用

    commons-io是一款处理io流的工具,封装了很多处理io流和文件的方法,可以大大简化我们处理io流和操作文件的代码.从common-io的官方使用文档可以看出,它主要分为工具类.尾端类.行迭代器 ...

  2. linux下java调用C

    linux下java调用C 分类: linux2012-05-22 09:12 1529人阅读 评论(0) 收藏 举报 javalinuxmakefilegccclasscommand 下面是在ubu ...

  3. java开发环境搭建(jdk安装)和经常出现问题的探讨

    面对许多java初学者环境搭建出现的问题 第一步: 1,首先在可以百度jdk进入oracle的官网也可以进入这个网站 https://www.oracle.com/technetwork/java/j ...

  4. python语法基础-函数-基础-长期维护

    ###############    函数的定义调用,返回值和返回值接收    ############## def mylen(): s = "myname" i = 0 for ...

  5. Contig|scaffold|N50|L50|NG50|贪心算法|de bruiji graph|

    生物信息学 Contig是reads拼成的连续的DNA片段,连续表达一个gene.通过双端测序的contig可确定contig之间的关系得到scaffold,Scaffold是reads拼成的有gap ...

  6. 89)PHP,跳转练习(1)

    首先是需要两个简单的文件: 目录关系是: 我的beifen.php代码展示,这个先执行: <?php header('Location:b.php'); b.php代码展示: <?php ...

  7. ZOJ-1183-Scheduling Lectures

    可以用贪心求最小讲课次数,贪心策略也很好想,就是对于任意主题,能早讲就早讲.这种方案的讲课次数一定是最少的,但是不满意指标不一定是最小,然后再利用动态规划求在最少讲课次数前提下的最小不满意指标. 方法 ...

  8. 赫夫曼解码(day17)

    思路: 传入map(字节与对应字节出现的次数)和最后生成的要传送的字节.将他们先转换成对应的二进制字节,再转换成原来的字符串. 代码: 12345678910111213141516171819202 ...

  9. 学习和使用 Styled Layer Descriptor SLD样式文件

    1. SLD 文件大致作用,可以浏览下示意图: 点要素的符号化:http://docs.geoserver.org/stable/en/user/styling/sld-cookbook/points ...

  10. geoserver整合swagger2支持自动生成API文档

    网上各种博客都有关于swagger2集成到springmvc.springboot框架的说明,但作者在整合到geoserver中确碰到了问题,调试一番最后才解决,遂总结一下. swagger2集成只需 ...