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值。这类临时对象用于初始化一个指向常量的引用时,在引用指向它们期间,这些临时对象会一直存在。(即:不会离开作用域并且析构函数被调用)

浙公网安备 33010602011771号