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 ...
随机推荐
- git常用命令(企业级)
一: 常用git命令 # 初始化,将已有的文件初始化为git仓库 git init # 查询文件状态[绿色暂存区,红色表示工作区更改了,没有提交到暂存区] git status git status ...
- SpringBoot实现统一异常处理
目录 前言 实现步骤 定义统一响应对象类 定义业务异常枚举接口和实现 定义业务异常基类 定义全局异常处理切面 测试和验证 总结 前言 近日心血来潮想做一个开源项目,目标是做一款可以适配多端.功能完备的 ...
- 小知识:Exadata平台去掉密码输错延迟10分钟登录
生产环境不评价,若是测试环境实在受不了偶尔一次因为密码输错就要等待10分钟才能登陆的限制. 那测试环境下,如何关闭这个限制呢?很简单: # vi /etc/pam.d/sshd --找到并注释掉下面这 ...
- Windows—通过Navicat导入MySQL示例数据库employees
Navicat是一套可创建多个连接的数据库管理工具,用以方便管理 MySQL.Oracle.PostgreSQL.SQLite.SQL Server.MariaDB .MongoDB 等不同类型的数据 ...
- Hive实战
1.使用hive实现WordCount (1) 创建数据库 create database wordcount; (2) 创建外部表 create external table word_data(l ...
- CF1886
A 分类讨论. B 二分. C 题意:给定一个字符串 \(s\).记 \(s_i\) 为将 \(s\) 删去 \(i\) 个字符,使得剩余字符串字典序最小得到的字符串.令 \(S=s_0+s_1+\d ...
- 多个request接口的功能优化处理速度
一.原始代码功能如下,包含两个request接口的调用,耗时情况约4秒 import datetime import time import requests start_time = datetim ...
- NC51180 Accumulation Degree
题目链接 题目 题目描述 Trees are an important component of the natural landscape because of their prevention o ...
- Kubernetes上使用Ingress Nginx将服务发布到外部IP
Kubernetes的网络结构 K8s的网络相对比较复杂, 包含了如下几类IP地址: Host Network 运行K8s集群的宿主服务器的内网IP, 其网段在配置宿主机时设置. 这些服务器可能是物理 ...
- fold命令
fold命令 fold命令用于限制文件列宽,其会从指定的文件里读取内容,将超过限定列宽的列加入增列字符后,输出到标准输出设备.若不指定任何文件名称,或是所给予的文件名为-,则fold命令会从标准输入设 ...