zoukankan      html  css  js  c++  java
  • 引用是具有特殊语义的指针

    从语义上理解

    引用就是变量的别名

    指针是一个变量,保存着变量的地址

    因为引用是别名,所以引用不能单独存在,没有空引用,而能有空指针

    但作为C++程序员,只从这个层面理解引用显然心里会发虚

    因此上测试代码

    #include <iostream>
    
    void t1() {
        char c = 'a';
        char &r = c;
        char *p = &c;
    
        r = 'b';
        *p = 'c';
    
        int size;
        
        size = sizeof(r);//1
        size = sizeof(p);//1
    
        char *q1;
        q1 = &r;
    
        char **q2;
        q2 = &p;
    }
    
    #pragma pack(1)
    struct T2A {
        char &_r;
        char _c;
    };
    #pragma pack()
    
    void t2() {
        char c = 'a';
        T2A s1{ c, 'b' };
    
        void *p;
        p = &s1;
        p = &s1._r;
        p = &s1._c;
    
        int size;
        size = sizeof(s1);//size值是5
    }
    
    void main() {
        t1();
        t2();
        
        system("pause");
    }

    代码本身没什么意思,有意思的是反汇编的结果

    t1的反汇编

        char c = 'a';
    00F61728  mov         byte ptr [c],61h  
        char &r = c;
    00F6172C  lea         eax,[c]
    00F6172F mov dword ptr [r],eax //引用r实际上是一个dword ptr类型 char *p = &c; 00F61732 lea eax,[c] 00F61735 mov dword ptr [p],eax //指针p看起来是不是和引用r在内存布局上一模一样? r = 'b'; 00F61738 mov eax,dword ptr [r] 00F6173B mov byte ptr [eax],62h *p = 'c'; 00F6173E mov eax,dword ptr [p] 00F61741 mov byte ptr [eax],63h //赋值操作,引用和指针也是一模一样 int size; size = sizeof(r); 00F61744 mov dword ptr [size],1 //但引用是一个语法糖,对引用操作的时候,编译器会把它换成被引用的对象 size = sizeof(p); 00F6174B mov dword ptr [size],4 char *q1; q1 = &r; 00F61752 mov eax,dword ptr [r] //取不到引用的地址,编译器给的是被引用对象的地址 00F61755 mov dword ptr [q1],eax char **q2; q2 = &p; 00F61758 lea eax,[p] 00F6175B mov dword ptr [q2],eax

    t2反汇编

        char c = 'a';
    00F640C8  mov         byte ptr [c],61h  
        T2A s1{ c, 'b' };
    00F640CC  lea         eax,[c] //取c的地址 
    00F640CF  mov         dword ptr [s1],eax  //s1的地址就是s1._r的地址,引用变量保存的是被引用对象的地址
    00F640D2  mov         byte ptr [ebp-18h],62h  //ebp-18h是s1._c的地址
    
        void *p;
        p = &s1;
    00F640D6  lea         eax,[s1] //取s1地址 
    00F640D9  mov         dword ptr [p],eax  
        p = &s1._r;
    00F640DC  mov         eax,dword ptr [s1]  //引用语法糖,想取s1._r的地址,实际上取到的是被引用对象c的地址
    00F640DF  mov         dword ptr [p],eax  
        p = &s1._c;
    00F640E2  lea         eax,[ebp-18h]  
    00F640E5  mov         dword ptr [p],eax  
    
        int size;
        size = sizeof(s1);
    00F640E8  mov         dword ptr [size],5  //引用变量_r 4字节,字符变量_c 1字节

    由此可见,引用的本质是指针,但有不同的语义

  • 相关阅读:
    C++面向对象三大特性
    4G通信技术LTE介绍
    汉澳战斗檄文,跟着汉澳去战斗
    AdapterView及其子类之二:使用ListActivity及ArrayAdapter创建列表
    [置顶] Objective-C ,ios,iphone开发基础:protocol 协议(委托,代理)的声明
    C语言中几种类型所占字节数
    UART, SPI, IIC的详解及三者的区别和联系
    数学基础详解 2——概率论与数理统计
    1—机器学习简介
    Python基础(11)——反射、异常处理
  • 原文地址:https://www.cnblogs.com/sqxy110/p/5072099.html
Copyright © 2011-2022 走看看