zoukankan      html  css  js  c++  java
  • C++学习笔记(四):引用的本质分析

    0x01 引用的意义

    • 引用作为变量别名而存在,因此在一些场合可以替代指针
    • 引用对于指针来说具有更好的可读性和实用性

    0x02 特殊的引用

    1. const引用

    在c++中可以声明const引用,用法如下:

    const Type& nmae = var;
    

    const引用让变量拥有只读属性,而不再拥有c++中的const进化属性。

    代码示例:

    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
    	int a = 4;
    	const int& b = a;
    
    	int* p = (int*)&b;
    
    	*p = 5;
    
    	printf("a = %d, b = %d
    ",a, b);
    	return 0;
    }
    
    

    运行结果:

    a = 5, b = 5
    请按任意键继续. . .
    

    当使用const修饰引用时,c++不再从符号表中取值,此时const引用变为了一个只读变量。

    2. 常量初始化的const引用

    当使用常量对const引用进行初始化时,c++编译器会为常量值分配空间,并将引用名作为这段空间的别名。所以简单来说,使用一个常量来初始化const引用,将生成一个只读变量。

    示例代码:

    void Demo()
    {
        printf("Demo:
    ");
        
        const int& c = 1;
        int* p = (int*)&c;
        
        //c = 5;
        
        *p = 5;
        
        printf("c = %d
    ", c);
    }
    
    int main(int argc, char *argv[])
    {
    
        Demo();
    
        return 0;
    }
    
    

    运行结果:

    Demo:
    c = 5
    请按任意键继续. . .
    

    0x03 引用的本质

    引用在c++内部的实现是一个指针常量

    Type& name ; <==> Type* const name

    c++编译器在编译过程中用指针常量作为引用的内部实现,因此引用所占用的空间大小与指针相同。

    从使用的角度,引用只是一个别名。

    示例代码:

    #include <stdio.h>
    
    struct TRef
    {
        char* before;
        char& ref;
        char* after;
    };
    
    int main(int argc, char* argv[])
    {
        char a = 'a';
        char& b = a;
        char c = 'c';
    
        TRef r = {&a, b, &c};
    
        printf("sizeof(r) = %d
    ", sizeof(r));
        printf("sizeof(r.before) = %d
    ", sizeof(r.before));
        printf("sizeof(r.after) = %d
    ", sizeof(r.after));
        printf("&r.before = %p
    ", &r.before);
        printf("&r.after = %p
    ", &r.after);
    
        return 0;
    }
    
    

    运行结果:

    sizeof(r) = 12
    sizeof(r.before) = 4
    sizeof(r.after) = 4
    &r.before = 00DAF938
    &r.after = 00DAF940
    请按任意键继续. . .
    

    函数返回引用示例代码:

    #include <stdio.h>
    
    int& demo()
    {
        int d = 0;
        
        printf("demo: d = %d
    ", d);
        
        return d;
    }
    
    int& func()
    {
        static int s = 0;
        
        printf("func: s = %d
    ", s);
        
        return s;
    }
    
    int main(int argc, char* argv[])
    {
        int& rd = demo();
        int& rs = func();
        
        printf("
    ");
        printf("main: rd = %d
    ", rd);
        printf("main: rs = %d
    ", rs);
        printf("
    ");
        
        rd = 10;
        rs = 11;
        
        demo();
        func();
        
        printf("
    ");
        printf("main: rd = %d
    ", rd);
        printf("main: rs = %d
    ", rs);
        printf("
    ");
        
        return 0;
    }
    

    运行结果:

    demo: d = 0
    func: s = 0
    
    main: rd = -2
    main: rs = 0
    
    demo: d = 0
    func: s = 11
    
    main: rd = -2
    main: rs = 11
    
    请按任意键继续. . .
    

    rd所代表的变量在函数返回时已经被销毁了,此时的rd是无意义的野指针。因此-2其实是一个随机值。

  • 相关阅读:
    精品教程Android程序的建立以及发布
    项目源码Android团购类客户端
    精品教程Android4.1开发环境搭建
    项目源码Android本地视频播放器
    精品教程Android组件详解
    精品教程NDK环境搭建(2)NDK的安装与配置
    ios 块语法的本质
    ios 属性易错点
    ios 打印结构体的方法
    ios开发 UITableCell 可重用问题
  • 原文地址:https://www.cnblogs.com/askta0/p/12732604.html
Copyright © 2011-2022 走看看