《C++深度剖析》学习日志九——深入探究const和引用
2018-02-07 22:29
197 查看
这篇日志是重头戏,const可以算是一般重要,但是引用关系到指针,就是非常重要了,大家都知道,C++最赖以生存的就是指针,好,接下来我们来一起探讨const和引用。
const
首先,我们都知道在C语言中,const修饰的是只读变量,而在C++中,const修饰的是常量,并且直接把常量放入符号表中待用,但事实真的是这样吗?究竟const什么时候为只读变量,什么时候为常量呢?让我们来分析下面代码。
#include <stdio.h>
int main()
{
const int x = 1;//进入符号表
const int& rx = x;//取x 的地址给rx
int& nrx = const_cast<int&>(rx);去掉rx的只读属性,并且使rx和nrx同地址
nrx = 5;//那么,x为1,rx为5,nrx为5,地址都一样
printf("x = %d\n",x);
printf("rx = %d\n",rx);
printf("nrx = %d\n",nrx);
printf("&x = %p\n",&x);
printf("&rx = %p\n",&rx);
printf("&nrx = %p\n",&nrx);
return 0;
}
看来我们的分析是正确的,那么他的评判标准是什么呢?
*const常量的判别标准
——只有用字面量(数字,字符等)初始化的const常量才会进入符号表
——使用其他变量初始化的const常量仍然是只读变量
——被volatile修饰的const常量不会进入符号表
在编译期间不能直接确定初始值的const标识符,都被作为只读变量处理
说完前两条,那么现在该验证第三条。
#include <stdio.h>
int main()
{
volatile const int y = 2;//不会进入符号表,只读变量
int* p = const_cast<int*>(&y);//取y的地址给p
*p = 6;//内存地址里的值改变,y即改变
printf("y = %d\n",y);
printf("p = %p\n",p);
return 0;
}
*const引用的类型与初始化变量类型
——相同:初始化变量成为只读变量
——不同:生成一个新的只读变量
#include <stdio.h>
int main()
{
volatile const int y = 2;
int* p = const_cast<int*>(&y);
*p = 6;
printf("y = %d\n",y);
printf("p = %p\n",p);
const int z = y;//是否为常量的标准是在编译期间,能否确定变量的值,y是变量,不是定值常量,所以生成只读变量
p = const_cast<int*>(&z);//去掉z的只读属性,并且z的地址给p
*p = 7;//z=7
printf("z = %d\n",z);//
printf("p = %p\n",p);
char c = 'c';
char& rc = c;
const int& nrc = c;//const的初始化变量类型不同,生成一个新的只读变量nrc
rc = 'a';
printf("c = %c\n",c);
printf("rc = %c\n",rc);
printf("nrc = %c\n",nrc);
return 0;
}
引用和指针本身没有关系,引用是变量的名字,而指针是变量,指向地址。但是在C++编译器的内部,是使用指针常量来实现引用,所以引用在定义时必须初始化。
在编程时,可以站在使用角度上看待引用,但在调试时,必须站在编译器的角度上,看待引用。
问:下面代码会报错吗?int a = 1;
int b = 2;
int* pc = new int(3);
int& array[]={a,b,*pc}; 站在使用者的角度看,没有问题,但是编译器所默认的数组元素的内存地址必须相邻,很显然,pc和b不一定相邻。所以在C++里不支持引用数组。
始值的const都是只读变量。
以上资料均来自狄泰,群号:199546072,志同道合的朋友可以加我:
qq:335366243
微信:zhong_335366243
const
首先,我们都知道在C语言中,const修饰的是只读变量,而在C++中,const修饰的是常量,并且直接把常量放入符号表中待用,但事实真的是这样吗?究竟const什么时候为只读变量,什么时候为常量呢?让我们来分析下面代码。#include <stdio.h>
int main()
{
const int x = 1;//进入符号表
const int& rx = x;//取x 的地址给rx
int& nrx = const_cast<int&>(rx);去掉rx的只读属性,并且使rx和nrx同地址
nrx = 5;//那么,x为1,rx为5,nrx为5,地址都一样
printf("x = %d\n",x);
printf("rx = %d\n",rx);
printf("nrx = %d\n",nrx);
printf("&x = %p\n",&x);
printf("&rx = %p\n",&rx);
printf("&nrx = %p\n",&nrx);
return 0;
}
看来我们的分析是正确的,那么他的评判标准是什么呢?
*const常量的判别标准
——只有用字面量(数字,字符等)初始化的const常量才会进入符号表
——使用其他变量初始化的const常量仍然是只读变量
——被volatile修饰的const常量不会进入符号表
在编译期间不能直接确定初始值的const标识符,都被作为只读变量处理
说完前两条,那么现在该验证第三条。
#include <stdio.h>
int main()
{
volatile const int y = 2;//不会进入符号表,只读变量
int* p = const_cast<int*>(&y);//取y的地址给p
*p = 6;//内存地址里的值改变,y即改变
printf("y = %d\n",y);
printf("p = %p\n",p);
return 0;
}
*const引用的类型与初始化变量类型
——相同:初始化变量成为只读变量
——不同:生成一个新的只读变量
#include <stdio.h>
int main()
{
volatile const int y = 2;
int* p = const_cast<int*>(&y);
*p = 6;
printf("y = %d\n",y);
printf("p = %p\n",p);
const int z = y;//是否为常量的标准是在编译期间,能否确定变量的值,y是变量,不是定值常量,所以生成只读变量
p = const_cast<int*>(&z);//去掉z的只读属性,并且z的地址给p
*p = 7;//z=7
printf("z = %d\n",z);//
printf("p = %p\n",p);
char c = 'c';
char& rc = c;
const int& nrc = c;//const的初始化变量类型不同,生成一个新的只读变量nrc
rc = 'a';
printf("c = %c\n",c);
printf("rc = %c\n",rc);
printf("nrc = %c\n",nrc);
return 0;
}
引用
引用和指针有什么关系呢,如何理解“引用的本质就是指针常量”?引用和指针本身没有关系,引用是变量的名字,而指针是变量,指向地址。但是在C++编译器的内部,是使用指针常量来实现引用,所以引用在定义时必须初始化。
在编程时,可以站在使用角度上看待引用,但在调试时,必须站在编译器的角度上,看待引用。
问:下面代码会报错吗?int a = 1;
int b = 2;
int* pc = new int(3);
int& array[]={a,b,*pc}; 站在使用者的角度看,没有问题,但是编译器所默认的数组元素的内存地址必须相邻,很显然,pc和b不一定相邻。所以在C++里不支持引用数组。
小结
指针是变量,引用是变量别名,const引用能生成新的只读变量,在C++内部,指针常量实现“引用”,便宜是不能确定初始值的const都是只读变量。
以上资料均来自狄泰,群号:199546072,志同道合的朋友可以加我:
qq:335366243
微信:zhong_335366243
相关文章推荐
- C++基础学习笔记----第六课(const和引用的扩展、重载函数和C方式编译的深入)
- 《C++深度剖析》学习日志一——const关键字
- 《C++深度剖析》学习日志二——引用
- 深入学习 const指针,const引用
- 4.1 jvm 深入学习之 java 引用
- 《C++深度剖析》学习日志三——内联函数
- C++中的引用深入学习笔记
- 【框架学习与探究之日志组件--Log4Net与NLog】
- VS2010 C++ 学习笔记(六) this指针 const 指针 引用
- 《C++深度剖析》学习日志四——函数参数
- 《C++深度剖析》学习日志五——函数重载(上)
- Github Mybatis深入学习之日志
- 深入学习GC之-GC日志解读
- const 引用——c++ primer 学习笔记
- Java学习笔记之深入理解引用
- PHP常量深入学习 define和const的区别
- 《C++深度剖析》学习日志六——函数重载(下)
- Hadoop深入学习:HDFS主要流程——SNN合并fsimage和编辑日志
- Java 深入学习(6) —— 打印 String 对象引用时显示的不是 hashCode 而是 String 对象本身的原因
- Scala学习日志(二)——深入模式匹配(一)