本文主要介绍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

最新文章

  1. Python爬虫爬取豆瓣电影名称和链接,分别存入txt,excel和数据库
  2. ArcEngine和GDAL读写栅格数据机制对比(二)—— IPixelBlock读写栅格
  3. [Angular 2] Move and Delete Angular 2 Components After Creation
  4. C# 在vs2010中打开vs2012的项目(转)
  5. Windows下 Scala开发环境搭建
  6. java Enum 用法示例
  7. [jQuery] $.grep使用
  8. Matlab单元(Cell)数据的应用
  9. 算法笔记_066:Kruskal算法详解(Java)
  10. LeetCode 381. Insert Delete GetRandom O(1) - Duplicates allowed (插入删除和获得随机数 常数时间 允许重复项)
  11. 基于线程池的线程管理(BlockingQueue生产者消费者方式)实例
  12. 轻量级集群管理软件-Ansible
  13. PyCharm连接远程服务器
  14. MSSQL sql server order by 1,2 的具体含义
  15. idea设置代码提示不区分大小写
  16. C# 有哪些集合
  17. 6、JVM--类文件结构(下)
  18. Android Notification的使用 - z
  19. springboot+mybatis结合使用
  20. Windows phone Toast消息推送 学习笔记

热门文章

  1. Wanna go back home
  2. 倾斜摄影数据转cesium 3D tiles工具介绍
  3. [LC] 23. Merge k Sorted Lists
  4. xpath-helper使用
  5. Pytorch中的variable, tensor与numpy相互转化的方法
  6. NDK开发之<cpu-features.h模块功能>
  7. makefile中的变量赋值
  8. Nginx 原理和架构
  9. DEBUG -- CLOSE BY CLIENT STACK TRACE问题的两种解决方案,整理自网络
  10. 多方论战!市场到底看重VR哪些特质