今天具体具体记录的是Compound Types,牵涉到指针(pointer)和引用(reference)。以前没有系统看过,只是会用。最近系统地整理下。
什么是Compound types?
是基于一般base type引申的类型。
宽泛的说,Declaration是一个type紧接着一系列的declarators, 为变量命名并赋予和base type相关的(复合)类型。
int &refVal = ival;
Here, int
is the type, &refVal
is declarators. Declarators可以是简单一个变量名,和我们之前提到的一致。
引用就是给object起一个别名。
当我们define一个reference的时候,intiailizer不再复制值,而是将这个值的引用绑定(bind)过去。和指针不同的是,一旦绑定,一生一世都得跟着一个object的,不能重新绑定。
int ival = 1024;
int &refVal = ival;
int &refVal2; // error: 这样定义是错的。
Reference变量用法都和原来一致,但要理解的是,操作refVal
的时候,实际就是在操作ival。所以若有修改引用,则会影响到原来变量。
除开特殊例子(const)啥的,一般情况下,Reference只能与object绑定,但不能和literal与表达式绑定。
Pointers 比 reference 来的更加宽泛:
The address-of operator (the & operator) is used to get the address of an object.
int ival = 42;
int *p = &ival;
注意以下四点Pointer特性
使用dereference operator(operator)去解引用。
int ival = 42;
int *p = &ival;
cout << *p;
空指针在C++可以用:0
, nullptr
, NULL
表示。
如果指针为空,那他的condition就是false。非空指针就是true。
比较宽泛,当我们不知道函数返回什么类型,或多种类型时使用。
从我个人实践经验,多是分配内存的函数使用(从C继承来的malloc),用之前都需要类型转换。Warning的主要来源。
int i = 1024, *p = &i, &r = i;
以上例子,是做理解declarator和initialize的集大成者。这里可以注意两点:
还有就是新手杀手,我当时一直没理解,现在看到书里提到了。
int* p;
int *p;
以上两句话,都是合法的,一点差别也没有。在cpp里面,operator可以不与name相邻,但是编译时还是同一意思。这里不能当做类型即为int来理解,实际上,还是按照p为一个整体(declarator)。
int* p1, p2; // p1 is pointer to int, while p2 is an int
*
意思是某基本类型的指针,**
意思是某基本类型指针的指针,***
意思是某基本类型的指针的指针的指针。
好活!写代码头秃来源:这是几层指针?还的解引用几次?
引用(reference)不是object,所以指针(pointer)不能指向reference。但是reference of pointer是可以的。
int i = 42;
int *p; // p is a pointer to t
int *&r = p; // r is a reference to the pointer p
r = &i;
*r = 0;
这里如何理解*&r
的type定义顺序呢?最好的方法是:越靠近name的越先作用。
比如这里*&是指针的引用,那他必须得先是个引用,所以&靠的更加近。