1、指针可以指向空:
int* ptr = null;//合法
2、引用必须指向一个确实存在的元素,引用在初始化的时候必须赋予初值,而指针可以不赋予初值:
int& n; //不合法,必须赋予初值 int* ptr; //合法
3、当引用指向的对象是局部变量时:
1 int& get_reference_of_tmp() 2 { 3 int num = 123; 4 int& n = num; 5 return n; 6 } 7 void do_something() 8 { 9 int num = 321; 10 } 11 12 int main(int argc, char* argv[]) 13 { 14 int& n = get_reference_of_tmp(); 15 printf("%d ", n); 16 do_something(); 17 printf("%d ", n); 18 getchar(); 19 return 0; 20 }
输出结果是:
123
321
也就是说:
返回的引用指向一个内存中栈空间,当局部变量的生命周期结束时,这个空间中的值不变,可以被使用,但是结果不可预期。
即:如果后面调用了其他函数,压入栈空间了一些新的数据,此时,引用的那个空间中的数据被改写,改写结果与后面调用的函数有关,前面的函数无法预期最终的结果。
4、当引用指向的对象不存在时:
1 int* ptr = null; 2 int& n = *ptr;
此时对n的操作将产生非法访问错误。
5、引用指向的目标位置不可改变,换句话说,对引用“赋初值”和“赋值”两种操作意义不同:
对引用赋初值是使该引用指向目标,对引用赋值是改变该引用所指目标的值;
而对指针“赋初值”和“赋值”操作的意义相同,都是使该指针指向新目标。
1 int a = 1; 2 int b = 2; 3 int& rfr = a; // 该操作时该引用指向了a 4 rfr = b; // 该操作不会使该引用指向b,而是改变了a的值 5 int* ptr = &a; // 该操作使该指针指向了a 6 ptr = &b; // 该操作使该指针指向了b
6、返回左值的操作符:*,.,->,[]等等,会涉及到操作符运算结果成为一个表达式的左值,此时,返回引用好于返回指针,因为返回指针需要进一步操作,如作*运算,而返回引用则不用进一步操作即可使用:
ptr->m_num = 10; obj.m_num = 10; str[i] = 'a'; *a = 10;