C++必知必会

 条款五:引用是别名而非指针

int a = 12;
int &ra = a;
--ra; // a == 11
a = 10; // ra == 10
int *ip = &ra; // ip 指向a

引用与指针的三大区别:

一,不存在空引用;

二,所有引用都要初始化;

三,一个引用永远指向用来对它初始化的那个对象;

1 Employee &anEmployee = *static_cast<Employee*>(0); // 错误!
2 
3 Employee *getAnEmployee();
4 //...
5 Employee &anEmployee = *getAnEmployee();
6 if (&anEmployee == 0) //如果getAnEmployee返回一个空指针,则其后代码未定义
7 
8 Employee *employee = getAnEmployee(); // good!用指针存放getAnEmployee返回结果
9 if (employee) //...

 一个引用初始化时它所指向的那个对象必须存在。is very important!

这个“别名”属性使得引用常常成为函数形参的优秀选择。

 1 template <typename T>
 2 void swap(T &a, T &b) {
 3     T temp(a);
 4     a = b;
 5     b = temp;
 6 }
 7 //...
 8 int x = 1, y = 2;
 9 swap(x, y); // x == 2, y == 1
10 
11 //引用可以为没有名字的对象赋予一个方便的名字:
12 int grades[MAX]
13 //...
14 swap(grades[i], grades[j]);

考虑下面代码:

1 inline void set_2d(float *a, int m, int i, int j) {
2     a[i * m + j] = a[i * m + j] * a[i * m + j] + a[i * m + j];
3 }

错误,

正确的改正:

1 inline void set_2d(float *a, int m, int i, int j) {
2     float &r = a[i * m + j];
3     r = r * r + r;
4 };

一个指向非常量的引用时不可以用字面值或临时值进行初始化的:

1 double &d = 12.3; // error!
2 swap( std::string("hello"), std::string(" , word") ); //error!

然而,一个指向常量的引用就可以:

1 const double &cd = 12.3; // ok
2 template<typename T>
3 T add(const T &a, const &b) {
4     return a + b;
5 }
6 //...
7 const std::string &greeting
8     = add(std::string("hello"), std::string(", world") ); // ok

 一个指向常量的引用采用一个字面值来初始化时,该引用实际上被设置为指向“采用该字面值初始化”的一个临时变量位置。如greeting引用则指向对add的调用所返回的无名临时string值。这类临时对象用于初始化一个指向常量的引用时,在引用指向它们期间,这些临时对象会一直存在。(即:不会离开作用域并且析构函数被调用)

 

 

 

 

 

 

 

 

posted @ 2013-03-22 22:58  ningjing@liunian  阅读(125)  评论(0)    收藏  举报