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. 用GUI完成了斗地主发牌

    JAVA真的很强大,简单的步骤他自己就可以帮助我们解决了,简单,方便,并且还有着非常大的开发潜力

  2. Java动手动脑(二)

    1>类的对象实例化 由于main为静态类型,所以在调用函数时也必须调用静态方法,如上代码中的求平方数的静态方法,如何在静态main中调用非静态类的方法呢? 静态方法只能直接访问静态成员,无法访问 ...

  3. iOS.ReactNative-3-about-viewmanager-uimanager-and-bridgemodule

    RCTViewManager and RCTUIManager 1. RCTViewManager 1.1 RCTViewManager 实现了接口RCTBridgeModule @interface ...

  4. 2-5. Working with Compile Time Constants

    #include <array> #include <cstdint> #include <iostream> class MyClass { private: u ...

  5. GPU高性能计算-CUDA

    前段时间有个同学的毕设是搞并行计算的,他基本不懂编程把我拉过去帮忙,我之前也没弄过,帮着搞了2天.先把代码贴上去,等有时间在把详细补充一些内容. CUDA编程主要是利用了显卡优越的并行计算能力,把一个 ...

  6. eyegaze

    1. eye_gaze https://github.com/iitmcvg/eye-gaze 2.deepgaze https://github.com/mpatacchiola/deepgaze ...

  7. 通过反射及注解的运用获取SQL语句

    import java.lang.reflect.*; public class BeanUtil { //这是拼接查询SQL语句的方法(getDelectSQL) public static Str ...

  8. python核心编程(第二版)习题

    重新再看一遍python核心编程,把后面的习题都做一下.

  9. javascript typeof

    https://zhidao.baidu.com/question/79159257.html typeof 运算符返回一个用来表示表达式的数据类型的字符串. 可能的字符串有:"number ...

  10. android studio 华为手机看不到具体的错误日志

    手机的开发人员选项打开了么,其中的 USB 调试打开了么?搞定他们并重新运行,是否能找到我们的日志?否,转到 2. 日志中是否有这样 could not disable core file gener ...