C++ 基础 引用

2018-10-14 10:49:00来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

1.引用的本质

  int b = 10;

  int &a = b;

  等效于:

  int * const a = &b;

  由于 a 是 const声明,所以一旦定义无法修改,所以要在定义时就要赋初值。

  实际使用时:

  a = 10;   ==> *b = 10;

 

2. 引用于函数结合

(1)引用做函数参数

int func(int &a)

{

   ...

}

使用时:

int b = 10; 

func(b);

为了分析语法,将其转换为指针,编译器在实参给形参赋值时:

int &a = b;   ===>   int *const a = &b;

实际使用:

a = 10; ===> *b = 10;

所以实现了间接赋值。

 

(2)引用做函数返回值

int &func()
{
   int ret = 10;
   return ret;
}

int main()
{
int a = func(); // gcc 中,这里出现段错误
int &b = func();
cout << a << endl;
cout << b << endl; // gcc 中,这里段错误
}

  在 VS 中,debug版本和 release版本的输出不同。

  所以上面的代码是错误的。

  分析原因:

  int a = func();  ==>  

          int &tmp = ret;  === >  int *const tmp = &ret;

          a = tmp;       ===>  a = *(&ret);

  其中 tmp 是 隐藏变量,一般在寄存器中。

  由于 函数返回后,局部变量 ret 空间释放,所以对无效空间的访问是未知的。

 int &b = func(); ==>

         int &tmp = ret;   ===> int *const tmp = &ret;

         int &b = tmp;     ===> int *const b = tmp;  ==>  int *const b = &ret;

 可以看出这里不存在非法地址访问,所以这句不会报错。

  cout << b << endl; ===> cout << *(&ret) << endl; 

  这里是非法地址访问。报错

  由于上面的非法地址访问的本质原因是栈空间的释放,所以如果变量的存储类在堆或数据段就不会有错。

 

3. 引用与指针

(1)引用指针

  int &b = c;

  int & * a = &b;

  上面的表达式是错误的,因为 指针不能指向引用,原因是 C++之父 不希望 引用和指针一样出现多级引用,同理也没有 引用的引用。

(2)指针引用

 int *b = &c;

int * & a = b;

  这是成立的,相当于:

int * * const a = &b;

 

4. 引用与 const 

(1)使用变量初始化常引用

int a = 10;

const int &b = a;

a = 11;  

b = 12;  // 错误

通过常引用赋予变量只读属性。

(2)使用字面量初始化常引用

int &a = 10;    // 错误,因为字面量没有地址,无法引用

const int &b = 10;  

常引用可以引用字面量,当常引用引用字面量时,C++编译器为字面量分配空间,并让常引用符号作为该空间的别名。

 

   

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:C++基础 const

下一篇:C++基础 inline 默认参数 函数占位参数 函数重载