复合类型
引用
引用(reference)
为对象起了另外一个名字。
1 | int ival = 1024; |
定义引用时,程序把引用和它的初始值绑定
在一起,而不是将初始值拷贝给引用。无法令引用重新绑定到另外一个对象,因此引用必须初始化。
引用即别名 引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。
定义了一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的:
1 | refVal = 2; // 把2赋值给ival |
指针
指针与引用类似,也实现了对其它对象的间接访问。不同于引用的是:
- 指针本身是一个对象,允许对其赋值和拷贝,生命周期内它可以指向几个不同的对象。
- 指针无需在定义时赋初值。
获取对象的地址
指针存放某个对象的地址,获取该地址需要取地址符 &
1 | int ival = 42; |
利用指针访问对象
如果指针指向了一个对象,则允许使用解引用符 *
来访问该对象。
1 | cout << *p; // 由符号*得到指针p所指的对象,输出42 |
空指针
空指针不指向任何对象。C++11初始化空指针的方法:
1 | int *p = nullptr; |
const限定符
关键字const
定义常量,const对象一旦创建后其值就不能再改变了,所以const对象必须初始化。
1 | const int bufSize = 512; |
const的引用
可以把引用绑定到const对象上,我们称之为对常量的引用
,对常量的引用不能被用作修改它所绑定的对象。
1 | const int ci = 1024; |
指针和const
指向常量的指针(pointer to const)
不能用于改变其所指对象的值,要想存放常量对象的地址,只能使用指向常量的指针。
1 | const double pi = 3.14; |
指针是对象而引用不是,允许把指针本身定为常量。常量指针(const pointer)
必须初始化,*放在const关键字之前用以说明指针是一个常量,即不变的是指针本身的值而非指向的那个值。
1 | int errNumb = 0; |
顶层const
用名词顶层const
表示指针本身是个常量,而用名词底层const
表示指针所指的对象是一个常量。
1 | int i = 0; |
处理类型
类型别名
类型别名(type alias)
是一个名字,它是某种类型的同义词。有两种方法定义类型别名:
传统方法是用关键字
typedef
1
2
3
4
5typedef double wages; // wages是double的同义词
typedef wages base, *p; // base是double的同义词,p是double*的同义词
typedef unsigned long (* _prepare_kernel_cred)(unsigned long cred);
_prepare_kernel_cred prepare_kernel_cred;以上两句就相当于:unsigned long (*prepare_kernel_cred)(unsigned long cred);
定义了一个函数指针prepare_kernel_cred,函数参数为(unsigned long cred),返回值为unsigned long。
建立一个类型别名的方法很简单,在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头。新标准使用
别名声明(alias declaration)
1
using SI = Sales_item; // SI是Sales_item的同义词
这种方法用关键字using作为别名声明的开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定成等号右侧类型的别名。
auto类型说明符
编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候就清楚地知道表达式的类型。然而有时做不到这样,因此,C++11新标准引入了auto类型说明符,它能让编译器替我们去分析表达式所属的类型,让编译器通过初始值来推算变量的类型。auto定义的变量必须有初始值。
1 | auto item = val1 + val2; // item初始化为val1和val2相加的结果 |
decltype类型指示符
有时希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量。C++11新标准引入了第二种类型说明符decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值:
1 | decltype(f()) sum = x; // sum的类型就是函数f的返回类型 |