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其实是一个随机值。

  • 相关阅读:
    A1023 Have Fun with Numbers (20分)(大整数四则运算)
    A1096 Consecutive Factors (20分)(质数分解)
    A1078 Hashing (25分)(哈希表、平方探测法)
    A1015 Reversible Primes (20分)(素数判断,进制转换)
    A1081 Rational Sum (20分)
    A1088 Rational Arithmetic (20分)
    A1049 Counting Ones (30分)
    A1008 Elevator (20分)
    A1059 Prime Factors (25分)
    A1155 Heap Paths (30分)
  • 原文地址:https://www.cnblogs.com/askta0/p/12732604.html
Copyright © 2011-2022 走看看