CONST


一、符号常量

声明:
const 类型说明符 常量名 = 常量值;
const float PI = 3.1415927; //可以交换const与float的位置

符号常量在声明时一定要赋值,而在程序中间不能改变其值。注:const与“类型说明符“可以互换,即

const int a = ;
int const a = ; //此两者等同

二、常对象及其常成员

2.1、常对象

声明:
const 类型说明符 对象名;
const Point p1(,); //可以交换const与Point的位置

常对象必须时这样的对象:它的数据成员值在对象的整个生存期间内不能被改变。也就是说,常对象必须进行初始化,而且不能被更新。

注:const与“类型说明符”也可以互换,但是人们更习惯于把const写在前面,即

const Point p1(,);
Point const p2(,); //此两者等同

2.2常成员函数

声明:
类型说明符 函数名(参数表)const;
void print()const;
//定义
void print()const{
cout<<r1<<";"<<r2<<endl;
}
  • const是函数类型的一个组成部分,因此在函数的定义部分也要带const关键字
  • 如果将一个对象声明为常对象,则通过该常对象只能调用它的常成员函数,而不能调用其它成员函数(这就是C++从语法机制上对常对象的保护,也是常对象唯一的对外接口方式)。
  • 无论是否通过常对象调用常成员函数,在常成员函数调用期间,目的对象都被视同为常对象,因此常成员函数不能更新目的对象的数据成员,也不能针对目的对象调用该类中没有用const修饰的成员函数(这就保证了在常成员函数中不会更改目的对象的数据成员的值)。
  • const关键字可以用于对重载函数的区分。例如,如果在类中这样声明,这是对print的有效重载。
//有效重载。非const对象调用该函数,编译器将选择最近的重载函数--不带cons关键字的函数
void print();
void print()const;

习惯:在适当的地方使用const关键字,是能够提高程序质量的一个好习惯。对于无需改变对象状态的成员函数,都应当使用const。

2.3常数据成员

声明:
private:
const int a; //可以交换const与int的位置

就像一般数据一样,类的成员数据也可以是常量,使用const说明的数据成员为常数据成员。

  • 如果在一个类中说明常数据成员,那么任何函数中都不能对该成员赋值。
  • 构造函数对该数据成员进行初始化,就只能通过初始化列表。
static const int b;    //静态常数据成员

const int A::b =     //静态常数据成员在类外说明和初始化

//注:之所以类的静态数据成员需要在类定义之外再加以定义,十四因为需要以这种方式专门为它们分配空间。非静态数据成员无需以此方式定义,因为它们的空间是与他们所属对象的空间同时分配的。
//在类外定义静态数据成员时无须加关键字static
static int count;
int Point::count = ;

三、常引用

定义:
const 类型说明符 & 引用名;
const Point &p1; //可以交换const和Point的位置
  • 常引用所引用的对象不能被更新。
  • 如果用常引用作形参,便不会意外地发生对实参的更改。
  • 非const的引用只能绑定到普通的对象,而不能绑定到常对象,但常引用可以绑定到常对象。
  • 一个常对象,无论是绑定到一个普通的对象还是常对象,通过该引用访问该对象时,都只能把该对象当作常对象
  • 对于基本数据类型的引用,则不能为数据赋值。对于类类型的引用,则不能修改它的数据成员,也不能调用它的非const的成员函数。

习惯:对于在汉书中无需改变其值的参数,不宜使用普通引用方式传递,因为那会使得常对象无法被传入,采用传值方式或者传递引用得方式可避免这一问题。对于大对象来说,传值耗时较多,因此传递常引用为宜。复制构造函数得参数一般也宜采用常引用传递。

四、const与指针

4.1、指向常量的指针(不能通过指针来改变所指对象的值)

const int *p1 = &a;     //指向常量的指针。
int b;
p1 = &b; //正确,p1本省的值可以改变
*p1 = ; //错误,不能通过p1改变所指的对象。但是a的值可以通过自己来改变,例如可以使用 a = 10; 另:const与int可以互换,语义相同
int const *p1 = &a; //与上面声明是等同的。

使用指向常量的指针,可以确保指针所指向的常量不被意外更改。如果用一般指针存放常量的指针,编译器就不能确保指针所指的对象不被更改。

4.2、指针类型的常量(指针本身不能被改变)

int * const p2 = &a;
p2 = &b; //错误,p2是指针常量,值不能被改变。
*pe = ; //正确,p2所指向的内容能通过指针来改变。

五、易混淆的地方

1、const与指针

常量与指针放在一起很容易让人迷惑。对于常量指针和指针常量也不是所有学习c++的人全都能说清的。例如:

const int *a1 = ;
int const *a2 = ;
int* const a3 = ;

上面两个表达式中,最易混淆的就是const到底修饰的是阵阵还是指针指向的区域?其实,我们只要记住:const指对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用。根据这个判断,a1应该是常量指针(即指向常量的指针,不能通过a1来修改它所指向的内容);而a2应该是指针常量(即m2中所存的地址不能被改变)。

当然,还可以从右向左读得方式记忆:

a1(a2) is a pointer to const int. 故*a1的内容不可以改变,但是a1可以指向别的int。

a3 is a const pointer to int. 故a2不能指向别的变量,但可以修改其指向的int的内容。

2、const 修饰函数传入参数

将函数传入参数声明为const,以指明使用这种参数是为了效率,并且不想让调用函数改变对象的值。将指针参数声明为const,函数将不修改这个参数所指向的对象。

void Fun( const A *in);    //修饰指针型为传入参数
void Fun( const A &in); //修饰引用型为传入参数

C++中的const总结的更多相关文章

  1. C++中的const

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

  2. C++中的const关键字

    http://blog.csdn.net/eric_jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方 ...

  3. C++中关于const的思考

    在学习C++的过程中,经常被什么时候使用const.为什么使用const以及怎么使用const关键字这样的问题所困扰,以下是我对const的使用总结. 1.值替代 使用#define的确单缺点,第一: ...

  4. C与C++中的const

    同样,有下面一段代码: #include <iostream> using namespace std; int main() { ; int *j = (int *) &i; * ...

  5. C++中加const与不加const的区别

    “常量”与“只读变量”的区别. 常量肯定是只读的,例如5, "abc",等,肯定是只读的,因为常量是被编译器放在内存中的只读区域,当然也就不能够去修改它. “只读变量”则是在内存中 ...

  6. C++笔记019:C++中的const修饰的是一个真正的常量

    原创笔记,转载请注明出处! 点击[关注],关注也是一种美德~ 程序一: 我们知道数组的下标不能为变量,必须是一个确定的值.在C语言中看程序: #define a 10 int main() { //第 ...

  7. C和C++ 中的const

    C++中的const正常情况下是看成编译期的常量,编译器并不为const分配空间,只是在编译的时候将期值保存在名字表中,并在适当的时候折合在代码中.所以,以下代码: #include <iost ...

  8. c++中的const和volatile知识自我总结

    学习了下c++中的const关键字,总结如下. 1.const限制一个变量不能修改其内容,如果强行修改的话,如下面代码这样子,编译就会报错,“表达式必须是可修改的左值”. int main() { c ...

  9. C++中的const的用法

    const对象.指向const对象的指针.const指针(通过一个面试题来了解)   1.const对象 (1)关于const,很多企业的笔试.面试都会出现,很简单,就问你“const的含义?”. 我 ...

随机推荐

  1. 2059 - Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(../Frameworks/caching_sha2_password.so, 2): image not found

    mac本地安装mysql后,navicat连接报错: - Authentication plugin ): image not found 解决方法 在控制台登陆后重新改下密码即可 ALTER USE ...

  2. 【CF1152F】Neko Rules the Catniverse(动态规划)

    [CF1152F]Neko Rules the Catniverse(动态规划) 题面 CF 题解 我们先考虑一个需要扫一遍所有位置的做法. 那么状态一定是\(f[i]\)然后什么什么表示考虑到当前第 ...

  3. promise和setTimeout执行顺序的问题

    提出问题,问题代码为 setTimeout(function(){console.log(1)},0); new Promise(function(resolve){ console.log(2) f ...

  4. UOJ 7 NOI2014 购票

    题意:给一棵树计算一下各个点在距离限制下以一定的费用公式通过不停地到祖先最后到达一号点的最小花费. 第一种做法:线段树维护带修凸壳.显然的,这个公式计算是p*x+q 所以肯定和斜率有关系.然后这题的d ...

  5. datable中table.row() not a funtion 解决方法

    解决办法一: 改为.DataTable({ (初始化时候) 解决办法二: 或者改为var data = myTable.api().row( this ).data();(获取值的时候)

  6. 解决beego1.12新版本没有log.info

    去https://github.com/astaxie/beego/中,找到旧的版本下载其log.go 至本地beego目录中

  7. 当前标识没有对“C:\WINDOWS\Microsoft.NET\...”的写访问权限的解决办法

    1.需要重新注册IIS服务扩展,在开始运行中输入以下命令运行:aspnet_regiis -i 32位的Windows: --------------------------------------- ...

  8. centos7-aliyun

    # 安装EPEL和IUS软件源 yum install epel-release -y yum install https://centos7.iuscommunity.org/ius-release ...

  9. ccf 201903-5 317任务

    [题目背景]“你在平原上走着走着,突然迎面遇到一堵墙,这墙向上无限高,向下无限深,向左无限远,向右无限远,这墙是什么?”——<流浪地球>原著我们带着地球去流浪了,为了处理流浪过程中可能会发 ...

  10. 关于dfs

    DFS 关于dfs,我的理解就是深度搜索,找到所有与入口相连的路径,可以用于迷宫求出口,利用递归的思想,进行搜索返回所有值. 比如,给你两个值分别表示迷宫的长和宽,迷宫有一个入口,一个出口,判断能否从 ...