c++深入理解const以及相关联的引用知识

/*
时间: 2018/11/12
书籍: c++primer 第五版 c++11标准
*/
const的分类

const分为两种, 一种是底层的const, 一种为顶层的const

  1. 底层const

    底层的const表示指向是常量, 指针本身是变量或者变量

  2. 顶层const

    顶层const表示指针本身是常量, 指向为变量或者常量

const的赋值含义
//省略头文件以及命名空间

int a[10] = {0};

int* c1 = a;  //可以通过c1改变数组的值, c1也可以指向其余数组
int* const c2 = a;//必须初始化, c2本身是一个常量, 只能指向a数组, 初始化就不能改变, 但是可以通过c2改变数组的值
const int* c3 = a;//无所谓初始化, 不能通过c3改变数组的值, 但是c3本身是一个变量, 可以指向其余的数组

//上述可得, c2就是顶层const, c3就是底层const

/*
时间: 2018/11/14
书籍: c++primer 第五版 c++11标准
P256
*/

在书籍的构造函数处, 关于初始化const数据成员的方法的时候总结下列几点

1. 如果成员是`const` , 引用, 或者属于某种未提供默认构造函数的类型, 我们必须通过构造函数初始化列表来为这些成员赋值
2. 构造函数的初始化应该和定义顺序一致, 并且避免使用用一个数据成员去初始化另一个数据成员

/*
时间: 2019/07/22
书籍: c++primer 第五版 c++11标准
P55
*/

补充以前对于const以及指针引用的错误理解

错误理解
1. 不能对常量进行引用 
 	以前理解为常量例如 20 40 等数值的引用, 以前的想法觉得肯定是错误的, 在书的P55面有详细的解释,如下:
 	常量引用是对const的引用
 	第一种以前的证明如下
 	#include <iostream>
	using namespace std;
	int main()
	{
		int &a = 2;	
		return 0;
	}
	在centos上的结果报错内容如下
	1.cpp: In function ‘int main()’:
	1.cpp:7: error: invalid initialization of non-const reference of type ‘int&’ from a temporary of type ‘int’

2. 引用时两边对象的类型必须保持一致
  	#include <iostream>
	using namespace std;
	int main()
	{
		double a = 22.0;
		int &b = a;
	}
	[root@hncuc Test]# g++ 1.cpp
	1.cpp: In function ‘int main()’:
	1.cpp:8: error: invalid initialization of reference of type ‘int&’ from expression of type ‘double’

 		   C++程序员经常把对const的引用简称为"常量引用", 严格的来说并不存在常量引用, 因为引用不是一个对象, 
 		所有我们没法让引用本身恒定不变.
 			事实上, 由于C++语言并不允许随便改变引用所绑定的对象, 所以从这层意义上理解所有的引用都算是常量
 			引用的对象是常量还是非常量可以决定于其所能参与的操作, 却无论如何都不会影响到对象和引用本身的
 			绑定关系特指出两个特殊情况
 		第一种情况: 初始化常量引用时允许用任意表达式作为初始值, 只要该表达式的值能够被转换为引用类型即可,
 				   尤其允许为一个常量引用绑定一个表达式and对象and字段例如:
 #include <iostream>
using namespace std;
int main()
{
        double a = 22.0;
        const int &b = a; //编译时 内部发生转换,建立一个中间变量来把22.0转换为int
          /* 
          		const int temp = a;
          		const int &b = temp; 
          */
        const int &c = 2; //常量引用
        const int &d = c * 2;//常量引用


        return 0;
}
接下来深入探讨一下如果当b不是常量的时候会发生什么事情, 这个时候b如果还能引用到a会发生什么事情呢, 我们知道编译器
会有这个转换的过程, 那么其实b引用的就是这个中间变量, 就算想通过赋值给b来改变a的值也会无法完成, 所以我们得出结论
只有加上const, 因为加上const以后我们无法改变这个引用的值,也就无法通过复制来改变绑定对象的值
由此我自己又产生一个疑问, 既然时常量那么无法改变, 那我们改变对象的值会不会对这个常量引用的值造成影响呢?
#include <iostream>

using namespace std;

int main()
{
        int i = 2;
        int &b = i;
        const int &c = i;
        b = 21;
        i = 15;
        cout << c << endl;
        return 0;
}
结果出乎意料, 输出c的值居然时15, 所以我们得出结论如下
当为常量引用的时候如果我们改变对象的值依然会对常量引用的值产生改变. 但是我们无法通过改变引用的值来改变对象, 理由就像
我们前面说的, 此时常量引用绑定的是编译器产生的中间变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值