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 ...
随机推荐
- CentOS7环境下MySQL的主从配置
CentOS7环境下MySQL的主从配置 一.什么叫主从复制 通过在主服务器和从服务器之间切分处理客户查询的负荷,可以得到更好的客户响应时间.通俗点说就是select查询发送到从服务器,修改数据的语句 ...
- Typora Mac中文破解版获取
作为程序员,markdown是非常好用的文本编辑语言,而Typora是非常好用的一款markdown编辑工具.Typora提供读者和作家的无缝体验.它删除了预览窗口,模式切换器,降低源代码的语法符号以 ...
- Java浅谈BufferedReader
既然Scanner简单好用,为什么要用BufferedReader呢? 主要原因是面对大量的读入显得较慢且不安全,这里体现在三个方面,一方面是解析的问题,好用意味着封装的更复杂,一拖n的接口解析起来会 ...
- 内存泄漏定位工具之 mtrace(二)
1 前言 mtrace(memory trace),是 GNU Glibc 自带的内存问题检测工具,它可以用来协助定位内存泄露问题.它的实现源码在glibc源码的malloc目录下,其基本设计原理为设 ...
- .net core微服务之网关
网关: 一:apisix doc:https://apisix.apache.org/zh/docs/apisix/getting-started/README/ github:https://git ...
- Vue+SpringBoot+ElementUI实战学生管理系统-5.用户管理模块
1.章节介绍 前一篇介绍了项目的API接口设计,这一篇编写用户管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.项目截图 列表操作 动态图 4 ...
- Java Socket编程系列(二)开发带回声功能的Server和Client
服务器端: package com.dylan.socket; import java.io.*; import java.net.ServerSocket; import java.net.Sock ...
- virtualbox中给redhat安装增强功能
关于虚拟机中安装redhat请参考其他教程: 1.点击虚拟机菜单:设备--安装增强功能.... 2.ssh连接到redhat,执行以下操作: [root@rhel-server ~]# mount / ...
- CDN 加速原理
=> CDN 加速原理 HTTP 请求流程说明: 用户在浏览器输入要访问的网站域名,向本地 DNS 发起域名解析请求. 域名解析的请求被发往网站授权 DNS 服务器. 网站 DNS 服务器解析发 ...
- 硬件开发笔记(二):硬件开发基本流程,制作一个USB转RS232的模块(一):开发基本过程和元器件选型
前言 做个usb转串口,同时兼容ttl,讲述硬件模块基础的开发流程,本篇描述了全流程过程,然后选型了合适的元器件. 基本流程 以下是笔者个人从事过相关硬件研发,总结出来的流程,仅代表个人意 ...