• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

Dean@cnbolg

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

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)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3