一.定义:

  引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样.

二.用法:

      1. 基本用法

        例如: int & a = b;

      2. 引用作为函数返回值

        先看一个例子:

         #include <iostream>
        using namespace std;
        class Node{
        int x;
        public:
        Node(const Node & n){//去掉copy函数关于h的输出结果神奇般相同,原因未知
        x = n.x;
        }
        Node(int x=):x(x){ }
        };
        int temp ;
        int & F(){
        temp*=;
        return temp;
        }
        int F1(){
        temp*=;
        return temp;
        }
        Node F2(){
        Node u();
        cout << &u << " ";
        return u;
        }
        int main(){
        temp = ;
        int &d = F(); //引用给引用,他们地址相同
        int e = F(); //引用给非引用,发生了复制
        const int & f = F();//把引用值赋值给常引用,他们的地址相同
        const int & g = F1();//对于内置数据类型,把非引用值赋值给常引用,他们的地址不同
        cout << &d << " " << &temp << endl;
        cout << &e << " " << &temp << endl;
        cout << &f << " " << &temp << endl;
        cout << &g << " " << &temp << endl;
        const Node & h = F2();//对于类对象类型,把非引用值赋值给常引用,他们的地址可能不同
        cout << &h << endl;
        cout << d << " " << temp << endl;
        return ;
        }
      3. 程序输出结果为:

        0x602194 0x602194
        0x7fffe0565418 0x602194
        0x602194 0x602194
        0x7fffe056541c 0x602194
        0x7fffe0565410 0x7fffe0565410
        80 80

          从结果中可以看到,当使用引用作为程序返回值并且将这个返回值赋值给引用类型时,他们的地址是相同的(都指向temp这个变量),其他情况都产生了值的赋值,发生了地址的变化。由此也可以看出,使用引用可以减少值的复制,特别是当需要传的数据特别大的时候。

      4. 另外,函数中返回非引用类对象赋值给const 引用变量时输出结果有些奇怪,不明白里面的copy函数为什么不调用但只加上就可以使他们的地址相同。
      5. 常引用
        基本用法如下:

        int b = ;
        const int a = b;

        使用常引用可以是引用的值不可修改。这样可以防止因误操作引发的数据修改,保证了安全性。

      6. 引用函数作为左值

        一般非引用函数都是只能作为右值,函数一旦计算完成那么它就是一个确定的常数。但引用函数不同。它既可作为左值,又可作为右值。

        int &d = ++F();

        相当于

        int A[];
        int &array = A;

        这是它作为左值的应用。

        但当我执行

        int &d = F()++;

        这样会产生错误。错误信息为:

        error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'

        这个错误信息与执行

        int &d = ;

        的错误信息一致,说明F()++操作实际上是相当于先把F()的值存到一个整型常量中,然后F()(相当于temp)的值加一.一个整型常量无法复制给int&类型。

        执行

        const int &d = F()++;(使用常引用)

        int d = F()++;(把常量值拷贝到变量中)

        才可以正常编译。

三.注意事项:

        • 引用不能用于数组,但可以用在指针上

          如果尝试执行

          int A[];
          int &array = A;

          编译器会报错:
          error: declaration of 'd' as array of references

          但我可以对指针用引用:

          int *p = A;
          int &array = p;

          编译成功。

          至于为什么不能对数组用引用,网上答案很多,我自己不能确定哪种答案是正确的,大家可以自行搜索相关问题。

        • 不要试图返回临时对象的引用,这样引用会成为无效引用,假如把返回值赋值给变量,那么程序可能会崩掉
        • 返回函数内部new分配的内存的引用或指针,这样的写法不推荐,很容易会造成内存泄漏(即无法正常的回收这块内存)
        • 注意常引用与普通引用之间的相互赋值问题
           temp = ;
          const int t = ;
          int &d = temp;
          const int &e = temp;
          const int &f = t;
          int &g = t;//编译错误

          常量变量都可以赋值给常引用,但只有变量值才可以给普通引用,若常量值给普通引用会发生编译错误。

        • 另外记录一次在写C++作业的过程中偶然发现的一个问题,这加深了我对常引用以及ostream重载等的一些理解。点击跳转

C++ 学习笔记之 引用的更多相关文章

  1. C++学习笔记2——引用

    1. int ival = 1; int &refVal = ival; //引用必须初始化,且类型严格匹配 2. int ival = 1; int &refVal = ival; ...

  2. (C/C++学习笔记) 十三. 引用

    十三. 引用 ● 基本概念 引用: 就相当于为变量起了一个别名(alias), △与指针不同的是它不是一个数据类型 通过引用我们可以间接访问变量,指针也能间接访问变量,但引用在使用上相对指针更安全. ...

  3. Java学习笔记-方法引用

    方法引用(Method Reference) 上一篇中记录了Lambda表达式,其可以创建匿名方法.当Lambda表达式只是调用一个存在的方法时,可以采用方法引用(JDK8具有的特性).如下: pub ...

  4. Java学习笔记day03_引用数据类型

    1.引用数据类型 步骤: 1. 导包   2. 创建引用类型变量 类型 变量名 = new 类型名();   3. 使用数据类型的功能 变量名.功能名(); 如Scanner类: import jav ...

  5. c++学习笔记之引用

    引用是 C++ 的新增内容,在实际开发中会经常使用:C++ 用的引用就如同C语言的指针一样重要,但它比指针更加方便和易用,有时候甚至是不可或缺的. 同指针一样,引用能够减少数据的拷贝,提高数据的传递效 ...

  6. c#学习笔记01——引用&类

    数据类型 值类型 bool 布尔值 True 或 False False byte 8 位无符号整数 0 到 255 0 char 16 位 Unicode 字符 U +0000 到 U +ffff ...

  7. c++ 学习笔记 c++ 引用C库注意点:#ifdef __cplusplus 倒底是什么意思?

    时常在cpp的代码之中看到这样的代码: #ifdef __cplusplus extern "C" { #endif //一段代码 #ifdef __cplusplus } #en ...

  8. HTML学习笔记 iframe引用页面按列(针对target打开方式解释) 第九节 (原创)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. CMake学习笔记六-引用cmake文件

    include(${CMAKE_CURRENT_SOURCE_DIR}/../Share/share.cmake)

随机推荐

  1. rz/sz:工作原理

    我们知道用linux命令rz/sz可以通过一些终端软件如secureCRT等在linux服务器与本地windows之间传文件.在服务器上rz一下,在本地windows下就跳出一个窗口,选择文件后就传到 ...

  2. Enable directory listing on Nginx Web Server

    1:Test environment [root@linux-node1 ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core ...

  3. excel 开头 结尾,中间 类似 SQL like ab% ,%ab ,%ab%

    excel  开头 结尾,中间  类似 SQL like 'ab%'  ,'%ab'  ,'%ab%' 在R2 单元格  查找   ab开头,ab结尾 =Search("ab",R ...

  4. ISAP学习笔记

    学完了ISAP,感觉心情舒畅,毕竟ISAP比Dinic好一点. 说到底ISAP其实是Dinic(不熟悉Dinic的人去我的博客找猴子课堂----最大流与最小割(看看思想),已经置顶)优化版,熟悉的人知 ...

  5. vim 版本更新

    sudo add-apt-repository ppa:jonathonf/vim sudo apt update sudo apt install vim 如果您想要卸载它, 请使用如下命令 sud ...

  6. CodeChef BIBOARD: Binary Board 命题报告

    这道题当时有了一点模糊的想法之后,构思了一整天-- 题意: 有一\(N \times M\)网格,每一格可以是白色或黑色.令\(B_i\)表示\(i \times i\)的纯黑子网格数量(子网格是指原 ...

  7. 安装 RobotFramework 可视化工具 RIDE

    1. 概述 robot framework 的安装 可视化工具 ride 的安装 2. 准备 安装缘由 来自一本书 书名: Robot Framework自动化测试修炼宝典 豆瓣上有好评不少, 坏评也 ...

  8. C#正则表达式提取HTML中IMG标签的SRC地址(转)

    一般来说一个 HTML 文档有很多标签,比如“<html>”.“<body>”.“<table>”等,想把文档中的 img 标签提取出来并不是一件容易的事.由于 i ...

  9. mfc通过MapWinGIS控件读取shp文件(通过#import实现)

    在MFC工程中想使用MapWinGIS组件,有多种方法可以实现, 第一种方法,#Import来实现 1.首先注册MapWinGIS ActiveX组件, 2.新建一个单文档工程:MapGis,为控件添 ...

  10. 使用conlleval.pl对CRF测试结果进行评价的方法

    基于CRF做命名实体识别系列 用CRF做命名实体识别(一) 用CRF做命名实体识别(二) 用CRF做命名实体识别(三) 评测 用CRF做完命名实体识别我们测试之后得到的结果就是预测的标签,并不能直接得 ...