C++中const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。const最常见用途是作为数组的界和switch分情况标号(也可以用枚举符代替),分类如下:

常变量:  const 类型说明符 变量名

常引用:  const 类型说明符 &引用名

常对象:  类名 const 对象名

常成员函数:  类名::fun(形参) const

常数组:  类型说明符 const 数组名[大小]

常指针:  const 类型说明符* 指针名 ,类型说明符* const 指针名

需要指明的是:const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用。在常变量(const 类型说明符 变量名)、常引用(const 类型说明符 &引用名)、常对象(类名 const 对象名)、 常数组(类型说明符 const 数组名[大小]), const与 “类型说明符”或”类名“(其实类名是一种自定义的类型说明符) 的位置可以互换。如:
     const int a=5; 与 int const a=5; 等同
     类名 const 对象名 与 const 类名 对象名 等同

一、常量与指针

 #include <stdio.h>
int main()
{
int k = ;
int q = ;
const int *pa = &k;
int *const pb = &k; printf("pa = %x *pa = %d | pb = %x *pb = %d\n",pa,*pa,pb,*pb);
//pa = pb = &k *pa = *pb = 100
// *pa = 99; //编译错误
*pb = ;
printf("pa = %x *pa = %d | pb = %x *pb = %d\n",pa,*pa,pb,*pb);
//pa = pb = &k *pa = *pb = 99
// pb = &q; //编译错误
pa = &q;
printf("pa = %x *pa = %d | pb = %x *pb = %d\n",pa,*pa,pb,*pb);
//pa = &q pb = &k *pa = 256 *pb = 99
return ;
}

const修饰指针变量时:

(1)只有一个const,如果const位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据;指针本身是变量,可以指向其他的内存单元。

(2)只有一个const,如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;指针所指的数据可以通过解引用修改。

(3)两个const,*左右各一个,表示指针和指针所指数据都不能修改。

二、常量与引用

  常量与引用的关系稍微简单一点。因为引用就是一个变量的别名,它本身就是一个常量。也就是说不能再让一个引用成为另外一个变量的别名, 那么他们只剩下代表的内存区域是否可变。即:

 int i = ;
const int& ri = i;// 正确:表示不能通过该引用去修改对应的内存的内容。
int& const rci = i;// 错误!不能这样写。

  由此可见,如果我们不希望函数的调用者改变参数的值。最可靠的方法应该是使用引用。下面的操作会存在编译错误:

 void func(const int& i)
{
i = ;// 编译错误!不能通过i去改变它所代表的内存区域。
}
int main()
{
int i = ;
func(i);
return ;
}

三、常量函数

(1)const修饰的成员函数不能修改除mutable修饰的变量之外任何的成员变量
(2)const成员函数不能调用非onst成员函数,因为非const成员函数可以会修改成员变量

 #include <iostream>
#include <stdio.h>
using namespace std; class Point{
public :
Point(int _x,int _y):x(_x),y(_y){}
void testConstFunction(int _x,int _y) const
{
// x=_x;//编译错误,在const成员函数中,不能修改任何类成员变量
// modify_x(_x);//编译错误,const成员函数不能调用非const成员函数,因为非const成员函数可以会修改成员变量
y = _y;
}
void modify_x(int _x){
x=_x;
}
int x;
mutable int y;
}; int main()
{
Point pt(,);
printf("x = %d y = %d\n",pt.x,pt.y);//x = 3 y = 5
pt.testConstFunction(,);
printf("x = %d y = %d\n",pt.x,pt.y);//x = 3 y = 7
return ;
}

四、常量返回值

很多时候,我们的函数中会返回一个地址或者引用。调用这得到这个返回的地址或者引用后就可以修改所指向或者代表的对象。这个时候如果我们不希望这个函数的调用这修改这个返回的内容,就应该返回一个常量。即:

 const int ff(); //返回的是常量,所以必须这么调用 const int a=ff()

C++之const的更多相关文章

  1. openssl 1.1.1 reference

    openssl 1.1.1 include/openssl aes.h: # define HEADER_AES_H aes.h: # define AES_ENCRYPT 1 aes.h: # de ...

  2. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  3. C++中的const

    一,C++中const的基本知识 1.C++中const的基本概念 1.const是定义常量的关键字,表示只读,不可以修改. 2.const在定义常量的时候必须要初始化,否则报错,因为常量无法修改,只 ...

  4. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  5. const let,console.log('a',a)跟console.log('a'+a)的区别

    const 创建一个只读的常量 let块级作用域 const let重复赋值都会报错 console.log('a',a) a console.log('a'+a) a2 逗号的值会有空格:用加号的值 ...

  6. es6之let和const

    在javascript中,我们都知道使用var来声明变量.javascript是函数级作用域,函数内可以访问函数外的变量,函数外不能访问函数内的变量. 函数级作用域会导致一些问题就是某些代码块内的变量 ...

  7. construction const parameter问题 构造函数const引用参数问题

    工程在window下编译没有任何问题, 但是在linux(CentOS6)下编译就老是报错 C++ 编译器已升级到最新版 6.1.0 错误如下: In file included /bits/stl_ ...

  8. Error:const char* 类型的实参和LPCWSTR类型的形参不兼容的解决方法。

    在C++的Windows 应用程序中经常碰到这种情况. 解决方法: 加入如下转换函数: LPCWSTR stringToLPCWSTR(std::string orig) { size_t origs ...

  9. C#基础知识七之const和readonly关键字

    前言 不知道大家对const和readonly关键字两者的区别了解多少,如果你也不是很清楚的话,那就一起来探讨吧!探讨之前我们先来了解静态常量和动态常量. 静态常量 所谓静态常量就是在编译期间会对变量 ...

  10. const 与 readonly知多少

    原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...

随机推荐

  1. LVM增大和减小ext4、xfs分区

    可以对ext4调整分区大小,能自动识别要增大还是减小 lvresize -L 300M -r /dev/vg/lvol0 原文地址http://www.361way.com/lvm-xfs-ext4/ ...

  2. 前端自动构建工具@gulp入门

    gulp是一个自动化的前端工具.它可以利用自身的插件来实现一些功能,如sass.less编译:浏览器自动刷新,文件压缩.重命名.代码校验(个人使用sublime的插件进行校验)等功能.当然这些功能也可 ...

  3. a 标签提交前验证

    最近在做验证的时候遇到了submit()与onsubmit()事件冲突的问题,本来想在a标签中添加submit()进行表单的提交,然后在 form中添加onsubmit事件触发验证方法.结果行不通,最 ...

  4. Bootstrap插件系列——Bootstrap-table初始化、分页、客户端搜索、服务端搜索

    又好久不写博客,最近项目都是用的bootstrap的样式,不出意外,应该是要在bootstrap的道路上越走越远了,所以下定决心,把bootstrap的插件都好好学学. 昨天写了boostrap-ta ...

  5. windows 下ssh 客户端

    今天用 xshell 和 bitvise ssh 在 windows 登录SSH ,发现 vi 一些中文内容的文件会出现乱码,配置无效,在网上找到一款不会中文乱码的SSH客户端 MobaXterm , ...

  6. 在vCenter5.5中为用户创建角色,管理虚拟机

    在vSphere的使用中,如有只有vCenter+ESXi节点的两级配置,为了达到多租户管理及权限分配,可以在vCenter5.5中为用户创建角色,管理虚拟机 1.以管理员身份登陆vCenter 2. ...

  7. Jfinal连接SQLSERVER相关配置说明

    driver=net.sourceforge.jtds.jdbc.Driver jdbcUrl = jdbc:sqlserver://localhost:1433;DatabaseName=test ...

  8. 深入研究C语言 第二篇

    1. 程序一: 首先我们研究如下程序: 回答如下问题: 1. 程序运行时n,a,b,c的段地址在哪个寄存器中? 全局变量的存储空间在什么段里?局部变量的存储空间在什么段了?参数在什么段里?函数的返回值 ...

  9. vue2 上传图片

    <template> <div class="vue-upload-img-multiple"> <div v-if="images.len ...

  10. iOS遍历相册中的图片

    //获取相册的所有图片 - (void)reloadImagesFromLibrary { self.images = [[NSMutableArray alloc] init]; dispatch_ ...