C++ 引用
引用
引用是一种不用*就能取到值的隐式指针,常用作函数的参数和返回值。
初始化
定义引用时,必须同时对其进行初始化。
int i = 10;
int& ri; // Error 引用需要设定初始值
初始化引用,可以用同类型变量或者另一个引用(需要是左值)。
int& r1 = i; //OK
int& r2 = r1; //OK
int& r3 = i + 1; //Error 需是左值
int& r4 = 100; //Error 需是左值
而以下引用的建立方式是错误的
int i[] = { 1, 2, 3};
int& ri = i; //Error i 是常量
int (&ri)[3] = i; //OK 包含3个元素的数组的引用 需要指定维度
int *p = i;
int& rp = p; //Error 引用与变量的类型不同 int vs. int*
int* & rp2 = p; //OK
int&& rri //Error 不能建立引用的引用
int& * pri //Error 不能建立引用的指针
注意:const引用可以被右值(表达式或常量)初始化。主要用作以右值的形式初始化const引用形参。参见下文const引用参数。
引用参数
作为函数形参的引用类型,实现了Pass-by-reference(C中只有pass-by-value)。
传递给该类函数的实参,需要满足可以正确初始化形参的条件,即必须是左值(参见上节初始化)
void fuc(int &i)
{
i *= 10;
}
fuc(r1); // OK 传递变量
fuc(r2); // OK 传递引用
const引用参数
在提高效率的同时,又保证传递的数据不被修改。
如果实参与引用形参不匹配,且形参引用是const,C++将生成临时变量,而修改临时变量是没有意义的(用后即焚),也正是因为如此,当形参是const时,因为程序不会修改数据,所以传递右值(临时变量)也无妨。同理,可以用右值初始化const引用。
int fuc2(const int& i)
{
return i * 10;
}
fuc2( i + 10); //OK
fuc3(100); //OK
数组引用形参
使用模板函数,传递任意大小的数组(引用)
template <typename T, const unsigned N> void fuc(const T (&a)[N]) //作为形参的数组引用 { for(const auto x : a) cout << x;
cout << " N = " << N <<endl; } int main(int argc, char* argv[]) { int i[] = {1,2,3}; char c[] = "hello world!"; fuc(i); //OK 编译器会实例化出 void mycpp(const int (&a)[3]) fuc(c); //OK 编译器会实例化出 void mycpp(const char (&a)[13]) //当然也可以建立对应的如下引用 int (&ri)[3] = i; //OK 包含3个元素的int数组的引用 char (&rc)[13] = c; //OK 包含13个元素的char数组的引用 }
返回引用
特点是表达式可以作为左值
int& fuc2(int& i)
{
return i *= 10; // 这里能return i * 10 吗? why?
}
int i = 3;
fuc2(i) += 3; // OK
一个典型的使用场景是重载操作符<< 略.
TIPS 要想确保返回的引用值安全,不妨提问:对象是否在函数之前已经存在? e.g.
char* & fuc2() { char * c = "hello "; return c; } string& fuc3() { string s = "world"; return s; } int main(int argc, char* argv[]) { //这些代码可以通过编译 cout << fuc2(); // OK - do u know WHY ? cout << fuc3(); // 运行时错误(未定义行为) }
bcoz the statement in fuc2 is constexpr
posted on 2017-03-10 18:07 Dean@cnbolg 阅读(126) 评论(0) 收藏 举报
浙公网安备 33010602011771号