这是第二篇C++学习笔记了,这一次,我放下了C++ Primer Plus而转向了C++ Primer,读了一些,感觉比C++ Primer Plus要简洁精炼,也是基于C++11的。本文主要与变量和类型有关。
作用域
作用域由{
开始,由}
结束。
这个其实是好理解的,我所接触过的语言都有作用域的概念。
当在内层作用域中定义了一个与外层作用域重名的变量时,该作用域中随后的对该变量的调用都是对这个局部变量的调用,但,如果我想要穿插着使用一下那个因为重名而被遮蔽(借自rust的术语)的全局变量呢?
书中给出的办法是使用::
作用域运算符,比如在main
函数外,你定义了int val = 9;
,该变量为全局变量。而在main
内,你又一次定义int val = 0;
,这个时候std::cout << val;
得到0
,而std::cout<< ::val;
输出9
。
虽然说可以这么做,但这毕竟太反模式了,不建议定义与全局变量重名的变量啊
引用
讲到引用,我一开始把它和指针弄混了,后来才发现这俩不太一样,使用引用的方式如下:
1 | int val = 1024; |
可见,引用可以说是原有对象的别名。引用本身不是对象,不能创建引用的引用。
引用的作用
C语言中大量利用指针作为形参或者函数返回值,这是由于值拷贝会有很大的消耗(比如传入传出一个大的结构体)。在C++之中使用引用作为函数参数和返回值的目的和使用指针是一样的,而且形式上更加直观,所以C++提倡使用引用。
指针与引用的区别:
- 指针是可以独立存在的; 但是引用不行
- 引用必须要进行初始化,指针没有必要
- 指针可以设置为NULL, 但是引用不行
- 引用一旦进行初始化之后,不会再改变其指向;但指针可以
以上特性让我认为引用可以作为指针的较为安全的替代品,但还是要注意不要把局部变量的引用传到外层作用域。
具体在函数中的使用,我还没有学到,再说吧。
const限定符
默认状态下,const对象仅在文件内有效。编译器将在编译过程中把用到const变量的地方都替换成对应的值。
当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。
解决的办法是,对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次就可以了:
1 | extern const int workers = 7; |
我们用名词顶层const(top-level const)表示指针本身是个常量,而用名词底层const(low-level const)表示指针所指的对象是一个常量。
常量指针既可以指向常量,也可以指向非常量,因为它是顶层const
类型别名
传统方式
可以使用typedef
来定义类型别名,语法如下:
1 | typedef 原类型 别名; |
C++ 11方法
使用using
关键字:
1 | using NewTypeName = ExistingType; |
NewTypeName
是你为新类型起的名字,它是你将来用来引用这个类型的标识符。
ExistingType
是现有的数据类型,你想为其创建别名。
个人感觉using
看着可读性更强。
decltype
decltype指示符用于让编译器推断出表达式所对应的类型
如:
1 | decltype(f()) result = x; |
result的类型与f()返回值的类型相同。
有一点要注意的:
decltype((var))
双层括号永远得到引用类型,如int&
,而decltype(var)
仅在var是引用的前提下才得到引用类型