C++中的引用

技术交流QQ群:1027579432,欢迎你的加入!

1.Cpp中的引用

  • 引用变量是一个别名,即它是某个已经存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

2.Cpp中的引用VS指针

  • 引用与指针之间的区别:
    • 不存在空的引用,引用必须要连接到一块的合法内存
    • 一旦引用被初始化为一个对象,就不能被指向另一个对象,指针可以在任何时候指向到另一个对象
    • 引用必须在创建时被初始化,指针可以在任何时间被初始化。

3.Cpp中创建引用

  • 可以把变量名称想象成为变量附属在内存位置的标签,可以把引用当成是变量附属在内存位置的第二个标签。因此,可以通过原始变量名称或引用来访问变量的内容。如下面的例子:
        int i = 7;
        int &r = i;  // r是一个初始化为i的int型引用
        double &s = d;  // s是一个初始化为d的double类型引用
    
  • 具体的程序实例如下:
            // 声明简单变量
            int i;
            double d;
            // 声明引用变量
            int &r = i; // 与int r = i;的区别是内存的分配,后者会再分配一个内存空间
            double &s = d;
    
            i = 5;
            cout << "i = " << i << endl;
            cout << "i的引用是: " << r << endl;
            cout << "i的地址是: " << &i << endl;
            cout << "r的地址是: " << &r << endl;
    
            d = 11.7;
            cout << "d = " << d << endl;
            cout << "d的引用是: " << s << endl;
    
            /*注意与上面的对比不同*/
            int x;
            int y = x;
            x = 6;
            cout << "x = " << x << endl;
            cout << "y = " << y << endl;
            cout << "x的地址是: " << &x << endl;
            cout << "y的地址是: " << &y << endl;
    

4.Cpp中的引用作为参数

  • 引用通常用于函数参数列表和函数返回值,两者的区别是:


    引用的作用.png
  • 4.1 引用作为函数参数
  • 引用作为函数参数,C++之所以增加引用类型,主要是把它作为函数参数,以扩充函数传递数据的功能。C++中函数传递参数的几种方法:
    • 将变量名作为实参和形参。这时传给形参的是变量的值,传递时单向的。如果在执行函数期间形参的值发生变化,并不传回给实参。因为在调用函数时,形参和实参不是同一个存储单元。
    • 传递变量的地址。形参是指针变量,实参是一个变量的地址。调用函数时,形参(指针变量)指向的是实参变量的内存单元,这种通过形参指针可以改变实参的值。
    • C++提供了传递变量的引用。形参是引用变量,和实参是一个变量。调用函数时,形参(引用变量)指向实参变量的内存单元,这种通过形参引用可以改变实参的值。
        void swap(int &x, int &y){
            int temp;
            temp = x;
            x = y;
            y = temp;
        }
    
        // 引用作为函数参数
            int a = 100;
            int b = 200;
            cout << "没有交换前a,b的值分别是: a = " << a << ",b = " << b << endl; 
            swap(a, b);
            cout << "交换后a,b的值分别是: a = " << a << ",b = " << b << endl;
    
  • 4.2 引用作为函数的返回值
  • 通过使用引用来代替指针,会使C++程序更容易阅读和维护。C++函数可以返回一个引用,方法与返回一个指针类似。当函数返回一个指针时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边,见下面的例子:
        // 引用作为函数的返回值
        double &setValues(int i, double *arr){
            return arr[i];
        }
        
        double vals[] = {10.1, 12.6, 3.14, 24.1, 50.5};
        cout << "数组没改变前的值: " << endl;
        for (int i = 0; i < 5; i++)
            cout << "vals[" << i << "] = " << vals[i] << endl;
        cout << "数组改变后的值: " << endl;
        setValues(1, vals) = 20.23;  // 改变数组的第2个元素
        setValues(3, vals) = 78.99;  // 改变数组的第4个元素
        for (int i = 0; i < 5; i++)
            cout << "vals[" << i << "] = " << vals[i] << endl;
    
  • 注意:当返回一个引用时,要注意被引用的对象不能超过作用域。所以,返回一个对局部变量的引用是不合法的,但是,可以返回一个静态变量的引用!
int & func(){
    int q;
    return q;  // 在编译时报错
    static int x;
    return x; // 安全,x在函数作用域外仍然是有效的
}
  • 引用作为函数返回值,其他注意地方:
    • 以引用返回函数值,定义函数时需要在函数名前加&
    • 用引用返回一个函数值的最大好处是:在内存中不产生被返回值的副本
    • 引用作为返回值时,必须遵守下面的规则:
      • 不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成了"无所指"的引用,程序会进入未知状态。
      • 不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况下(返回函数内部new分配内存的引用),又会面临其他尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成内存泄漏。
      • 可以返回类成员的引用,但是最好是const。主要原因是当对象的属性是与某种业务规则相关联的时候,其赋值常常与某些其他属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其他对象可以获得该属性的非常量引用(指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。

5.C++中的引用类型总结

  • 引用:就是变量的一个别名,作为别名来说,一个变量不能只有别名,而没有自己的真实姓名。


    引用的形象化表示.png
  • 5.1 基本数据类型的引用
        int a = 3;
        int &b = a;  // b就是a的引用,即b是a的一个别名;引用必须初始化,否则会编译错误
        b = 10;
        cout << "a = " << a << endl; // 此时a的值已经由原来的3变成了10,因此对别名b做任何操作,其实质都是对变量a本身做操作!
    
  • 5.2 结构体类型的引用
        typedef struct{
            int age;
            char name;
            double salary;
        }Student;
    
        void print_info(){
            Student s1; // 定义一个结构体变量,s1
            Student &s = s1; // 给s1起了一个别名叫s
            s.age = 20;  // 通过引用给结构体变量的数据成员赋值
            s.name = 'A';
            cout << "s.age = " << s.age << ", s.name = " << s.name << endl;
        }
    
        print_info()  // 调用上面的函数
    
  • 5.3 指针类型的引用
  • 指针类型的引用是当中最复杂的,最难理解的,同时在写法上也不一样。定义:
        类型 *&指针引用名 = 指针;
    
  • 参见下面的实例:
        // 指针类型的引用
        int m = 10; // 定义一个整型的变量a
        int *p = &m; // 定义一个指向变量a的指针p
        int *&p_reference = p;  // 定义指针p的引用p_reference即是p的别名
        *p_reference = 20; // 把20赋值给*p_reference,相当于把20赋值给*p,也就是相当于把值赋值给a
        cout << "m = " << m << endl;
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • 技术交流QQ群:1027579432,欢迎你的加入! 1.Cpp中的指针 每个变量都有一个内存位置,每一个内存位置...
    CurryCoder阅读 2,686评论 0 1
  • 题目类型 a.C++与C差异(1-18) 1.C和C++中struct有什么区别? C没有Protection行为...
    阿面a阅读 7,654评论 0 10
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,515评论 1 51
  • const 引用 const 引用是指向 const 对象的引用:const int ival = 1024;co...
    rogerwu1228阅读 633评论 0 1
  • 指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法。 1...
    起个名字真难啊2015阅读 4,733评论 0 4