const用法及与constexpr区别总结
1、用const修饰函数的参数
参数是值传递
由于函数将自动产生临时变量复制该参数,该参数无需保护,没必要用
const参数是指针传递或者引用传递
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区别
对于修饰Object来说
const并未区分出编译期常量(编译时就可以确定的常量表达式)和运行期常量constexpr限定在编译期常量,也就是说,编译器看见constexpr就可以在编译期计算,所以应该尽量将一个变量声明为constexpre
对于修饰函数来说
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区别总结的更多相关文章
- 【转】话说C语言const用法
原文:话说C语言const用法 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修 ...
- const 用法全面总结
C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...
- const用法详解(转)
http://www.cnblogs.com/StudyRush/archive/2010/10/06/1844690.html 面向对象是C++的重要特性. 但是c++在c的基础上新增加的几点优化也 ...
- const 在C++中的区别
一.Const作用 如下表所示: No. 作用 说明 参考代码 1 可以定义const常量 const int Max = 100; 2 便于进行类型检查 const常量有数据类型,而宏常量没有 ...
- JavaScript中const、var和let区别浅析
在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始 ...
- c++ const用法小结
const用法 1,定义全局变量的内存分配问题 #define Pi_1 3.14 //使用#define宏 const double Pi_2 = 3.14 //使用const ...
- 实例讲述PHP面向对象的特性;;;php中const与define的使用区别
php中const与define的使用区别 1.const:类成员变量定义,一旦定义且不能改变其值. define:定义全局常量,在任何地方都可以访问.2.define:不能在类中定义,而const可 ...
- const用法
一.const作用 二.const用法 1.修饰一般常量 修饰符const可以用在类型说明符前,也可以用在类型说明符后. 例如: ; ; 2.修饰常数组 修饰符const可以用在类型说明符前,也 ...
- 浅谈HTTP中GET、POST用法以及它们的区别
浅谈HTTP中GET.POST用法以及它们的区别 HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符.我们可以这样认为: 一 ...
- static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符
一.static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝 C++ Code 1 2 3 4 5 6 7 8 9 10 11 ...
随机推荐
- 教你用JavaScript实现背景图像滑动
案例介绍 欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用JavaScript编程实战案例,做一个背景图像滚动效果.滚动鼠标背景图像缩小,下方滑动出现文字.通过实战我们将学会obj. ...
- CH57x/CH58x/CH59x iBecaon广播
首先要先了解iBecaon.iBecaon是苹果基于BLE广播的一个技术规范:只要设备生产商符合特定标准,就可以要求苹果授权它们在其设备上使用"iBeacon" 商标. 在设备生产 ...
- 【JS】因两道Promise执行题让我产生自我怀疑,从零手写Promise加深原理理解
壹 ❀ 引 其实在去年七月份,博客所认识的一个朋友问了我一个关于Promise执行先后的问题,具体代码如下: const fn = (s) => ( new Promise((resolve, ...
- 精读JavaScript模式(九),JS类式继承与现代继承模式其二
壹 ❀ 引 二零一九年的三月二十号,我记录了精读JavaScript模式(八)这篇读书笔记,今天是二零二零年三月十五号,相差五天,其实也算时隔一年,我重新拿起了这本书.当前为什么没继续写下去呢,主要还 ...
- UVALive7146 Defeat the Enemy
题目链接 题目 见链接. 题解 知识点:贪心,STL. 首先要保证我方军队能消灭对方军队才行,因此只要我们按攻击力从大到小排,对方按防御力从大到小排,从大到小遍历,用我方所有攻击力大于敌方目前防御力军 ...
- CentOS在无网络环境下,用离线源yum安装软件
先说大致步骤: 1.前提假设:当前无网络的目标服务器是A,我们需要先准备一台服务器B: 2.在B上面用yum先把软件安装完成. 3.然后用createrepo将B中的包拷贝出来,并传到A上(用U盘或者 ...
- SpringCloud Alibaba Sentinel实现熔断与限流<2020-9>
SpringCloud Alibaba Sentinel 1.Sentinel是什么? 1.1.前言说明: 作用:实现熔断与限流 (Hystrix断路器 升级版) 文档直达: 官网中文文档 1.2.S ...
- win32 - Session 0 隔离
在Windows XP,Windows Server 2003和Windows操作系统的早期版本中,所有服务都与登录控制台的第一个用户在同一会话中运行.该会话称为会话0.在会话0中一起运行服务和用户应 ...
- RAID 10磁盘阵列实践
RAID概述 RAID技术通过把多个硬盘设备组合成一个容量更大.安全性更好的磁盘阵列,利用分散读写技术来提升磁盘阵列整体的性能,同时把多个重要数据的副本同步到不同的物理硬盘设备上,从而起到了非常好的数 ...
- Lucene介绍与使用
Lucene介绍与使用 原文链接:https://blog.csdn.net/weixin_42633131/article/details/82873731 不选择使用Lucene的6大原因? 原文 ...