C++ const用法,看这一篇就够了!
本文主要介绍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:
- 引用只是一个变量的别名,不是对象,因此引用不会占用存储空间
- 调用一个返回引用的函数得到左值,其他返回类型得到右值
2. 类定义中使用const
2.1 类成员
class Test{
public:
Test():a(10){}
void display();
private:
const int a;
};
- 类定义中不能进行初始化,因为在头文件中定义只是一个声明,并没有分配真正空间,因此变量是不存在的,因此是不能赋值的。
- 在类定义外部,const定义的变量是不能被赋值
问题:
类定义中不能赋值,类定义外部也不能赋值,但是又必须赋值,这可如何是好?
解决方案:
- 在构造函数后的参数初始化列表中初始化
- 将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. 参考资料
- C++ primer 第五版-P57、P201、P231、P247
- C++ non-const lvalue reference cannot bind to a temporary
C++ const用法,看这一篇就够了!的更多相关文章
- Java中的多线程=你只要看这一篇就够了
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- 关于 Docker 镜像的操作,看完这篇就够啦 !(下)
紧接着上篇<关于 Docker 镜像的操作,看完这篇就够啦 !(上)>,奉上下篇 !!! 镜像作为 Docker 三大核心概念中最重要的一个关键词,它有很多操作,是您想学习容器技术不得不掌 ...
- JVM内存模型你只要看这一篇就够了
JVM内存模型你只要看这一篇就够了 我是一只孤傲的鱼鹰 让我们不厌其烦的从内存模型开始说起:作为一般人需要了解到的,JVM的内存区域可以被分为:线程栈,堆,静态方法区(实际上还有更多功能的区域,并且这 ...
- 【java编程】ServiceLoader使用看这一篇就够了
转载:https://www.jianshu.com/p/7601ba434ff4 想必大家多多少少听过spi,具体的解释我就不多说了.但是它具体是怎么实现的呢?它的原理是什么呢?下面我就围绕这两个问 ...
- [转帖]nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件
nginx学习,看这一篇就够了:下载.安装.使用:正向代理.反向代理.负载均衡.常用命令和配置文件 2019-10-09 15:53:47 冯insist 阅读数 7285 文章标签: nginx学习 ...
- 2019-5-25-win10-uwp-win2d-入门-看这一篇就够了
title author date CreateTime categories win10 uwp win2d 入门 看这一篇就够了 lindexi 2019-5-25 20:0:52 +0800 2 ...
- 鸿蒙应用程序Ability(能力)看这一篇就够
本节概述 什么是Ability Ability分类 Ability生命周期 Ability之间跳转 什么是Ability Ability意为能力,是HarmonyOS应用程序提供的抽象功能.在Andr ...
- windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看
windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看 1. 新建excel表格 A B C D E 姓 名 全名 登录名 密码 李 四 李四 李四 test123!@ ...
- 什么是 DevOps?看这一篇就够了!
本文作者:Daniel Hu 个人主页:https://www.danielhu.cn/ 目录 一.前因 二.记忆 三.他们说-- 3.1.Atlassian 回答"什么是 DevOps?& ...
- python面试看这一篇就够了
python-面试通关宝典 有面Python开发方向的,看这一个repo就够啦? 语言特性 1.谈谈对 Python 和其他语言的区别 Python属于解释型语言,当程序运行时,是一行一行的解释,并运 ...
随机推荐
- python-django项目-Linux系统建立django项目_20191117
python-django项目-Linux系统建立django项目 1,Linux系统下面,cd /usr/local/lib/ 看这个下面会有两个python版本,一个2.7,一个3.5,我们使用 ...
- Excel-DNA项目只用1个文件实现Ribbon CustomUI和CustomTaskpane定制【VB.Net版】
Excel-DNA项目中的自定义功能区和自定义任务窗格需要用到各种命名空间.添加所需文件,才能实现.后来我发现可以把所有代码都写在Class1.vb这个默认文件中. 大家可以在Visual Studi ...
- java成神之路
一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133 http://i ...
- [LC] 1099. Two Sum Less Than K
Given an array A of integers and integer K, return the maximum S such that there exists i < j wit ...
- 吴裕雄 python 神经网络——TensorFlow 卷积神经网络水果图片识别
#-*- coding:utf- -*- import time import keras import skimage import numpy as np import tensorflow as ...
- 三、RabbitMQ安装
安装前准备 Linux版本信息: 发行版本:CentOS Linux release 7.5.1804 (Core) 内核版本:Linux version 3.10.0-862.el7.x86_64 ...
- Qt 多线程QThread实现方法之一
基本思想 在主线程中,哪里需用多线程,就在哪里创建一个QThread实例: 把耗时操作封装到一个继承于QObject的子类(这里叫做工作类Worker)槽函数中: 创建QThread实例和Worker ...
- 再举个webstrom 正则应用例子。
要将 "_behavior_chineseobj":{ "场所内网IP地址":"IP_ADDRESS", "源外网IPv4地址&q ...
- 史无前例的KDD 2014大会记
2014大会记" title="史无前例的KDD 2014大会记"> 作者:蒋朦 微软亚洲研究院实习生 创造多项纪录的KDD 2014 ACM SIGKDD 国际会 ...
- GOM通区插件-支持GOM绝对路径-读取配置项-分割字符等功能。不定期更新
A-A+ 2019年07月19日 Gom引擎 阅读 45 views 次 [@Main] #IF #SAY [<读配置项/@读配置项>] [<写配置项/@写配置项>] [& ...