• C++ 引用本质的详解


    //引用本质的理解①
    #include<iostream>
    using namespace std;
    
    int GetA(){
        int a = 10;
        return a;
    }
    
    int & GetB(){
        int a = 10;
        printf("a的地址是%x
    ", &a);
        return a;
    }
    
    void main(){
        int a1 = 10, a2 = 0;
        a1 = GetA();
        printf("a1的值是%d
    ", a1);
        //打印 10
        //经过仔细观察内存发现   return a;这句话执行完毕后   c++编译器并没有立刻销毁a所标识的内存空间
        //而是执行完  a1 = GetA(); 这个赋值操作之后  才会销毁内存空间
        //所以 变量a1能够接受到局部变量a的值   打印10不是偶然成功的
    
        a2 = GetB();
        //前置说明 int &b=a; 
        //引用本质上就是个常指针  b是个指针  但是引用指针b的指向的内存空间不可以改变
        //c++编译器内部完成的是  ①创建一个int * const类型的常指针  b 
        //② 将变量a的地址赋值给常指针 b
        //当c++编译器发现有操作需要对(引用指针)b进行取值或者赋值操作的时候 
        //c++编译器会默认 对b进行一个 提领 *p操作----这都是c++编译器内部行为(所以c++才会这么慢  自己隐形的做了好多操作)
        //例如  printf("b=%d
    ",b);  此时本质上是 printf("b=%d
    ",*b);
        //又例如  b=20;   本质上是 *b=20;
        //再次强调  默认对指针进行 提领 * 操作   只是c++对引用指针的一种特殊处理 ; c++编译器不会对别的指针 默认进行 提领 * 操作
    
        //如此一来  我们来分析一下  函数 GetB()
        //当GetB()  return a;的时候  等于是  c++编译器定义了一个临时引用指针  temp
        //将变量a的地址赋值给临时引用指针 temp  
        //执行  a2 = GetB();  实际上是执行  a2=*temp;   
    
        //经过仔细观察发现   return a;这句话执行完毕后   c++编译器并没有立刻销毁a所标识的内存空间
        //而是执行完  a2 = GetB();  这个复制操作之后  才会销毁局部变量a的内存空间
        //所以此时的 a2=*temp;   完全有效
        // "="  赋值操作  是将局部变量a的值复制到 a2所标识的内存空间里
    
        printf("a2的地址是%x
    ", &a2); //打印  a4f754
        printf("a2的值是%d
    ", a2);   //打印 10
    
        
    
        int &a3 = GetB();
    
        //同理  对于 int &a3 = GetB();  本质上可以这样写   int &a3=*temp;
        //此时  *temp是有值的  因为执行到 int &a3 = GetB();的时候   局部变量a的内存空间还没有被释放
        //定义int &a3=*temp;   那么c++编译器  将把*temp的地址赋值给引用指针a3(a3=temp;)即会把指针temp的值赋值给指针a3
        //引用指针temp的值 也就是 &a (a的地址)
        //当执行 printf("a3的值是%d
    ", a3);  本质上是执行  printf("a3的值是%d
    ", *a3); 
        //但是int &a3 = GetB();执行完成之后  局部变量a的内存空间已经被释放了
        //temp所指向的内存空间的数据已经被系统重置了  所以 *temp的数据只能是脏数据了  a3又等于 temp
        //因此*a3得数据也是脏数据
    
        printf("a3的地址是%x
    ", &a3);  //  打印  a4f664   此时  局部变量a的地址 也是 a4f664
        printf("a3的值是%d
    ", a3);   //脏数据
        system("pause");
    }
  • 相关阅读:
    Java加密作业
    作业
    思考动手
    方法作业
    课堂2数字输出
    字符型转整形
    课堂验证作业
    Eclipse @override报错解决
    用注解配置动态代理
    动态代理模式
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5585885.html
Copyright © 2020-2023  润新知