C++ 引用本质的理解①

//引用本质的理解①
#include<iostream>
using namespace std;

int GetA(){
    int a = 10;
    return a;
}

int & GetB(){
    int a = 10;
    printf("a的地址是%x\n", &a);
    return a;
}

void main(){
    int a1 = 10, a2 = 0;
    a1 = GetA();
    printf("a1的值是%d\n", 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\n",b);  此时本质上是 printf("b=%d\n",*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\n", &a2); //打印  a4f754
    printf("a2的值是%d\n", 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\n", a3);  本质上是执行  printf("a3的值是%d\n", *a3);
    //但是int &a3 = GetB();执行完成之后  局部变量a的内存空间已经被释放了
    //temp所指向的内存空间的数据已经被系统重置了  所以 *temp的数据只能是脏数据了  a3又等于 temp
    //因此*a3得数据也是脏数据

    printf("a3的地址是%x\n", &a3);  //  打印  a4f664   此时  局部变量a的地址 也是 a4f664
    printf("a3的值是%d\n", a3);   //脏数据
    system("pause");
}
时间: 2024-10-20 05:17:40

C++ 引用本质的理解①的相关文章

追本溯源 回归本质--深入理解抽象类和接口

挺不错的文章,以面向对象设计的高度审视抽象类和接口的本质 原文地址:http://dev.yesky.com/436/7581936.shtml 在 Java 语言中, abstract class 和 interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的面向对象能力.abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进 行抽象类定义时对于abstract class和in

JAVA不可变类与可变类、值传递与引用传递深入理解

一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: Person.java package cn.qlq.test; public class Person { private int age; private String name; public int getAge() { return age; } public void setAge(int

一次阿里面试后对函数本质的理解

一次阿里面试后对函数本质的理解 写在前面 环境:阿里的在线编程系统允许面试官在线考察面试者的编程能力. 考点:编程和理论. 编程:分为技术自驱力.异步操作.编程风格(颗粒小).变量作用域.DOM操作等. 理论:性能优化,浏览器运行机制,协议/标准等 本文侧重于编程,在编程中对函数的运用是写好程序的基础.(参考开发者技能修炼的五个等级中"第二阶梯:Developer,开发工程师""知道了变量.逻辑与函数的意义") 抛出一个问题 如何写一个信号灯?(参考一道关于Prom

C++:引用的简单理解

前言:引用是C++一个很重要的特性,最近看了很多有关引用的资料和博客,故在此对引用的相关知识进行总结 一.什么是引用 引用,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作完全等价 语法:类型 &引用名=目标变量名: 特别注意: 1.&不是求地址运算符,而是起标志作用 2.引用的类型必须和其所绑定的变量的类型相同 1 #include<iostream> 2 using namespace std; 3 int main(){ 4 double a=

c++ 关于引用 &amp;的进一步理解

在很久以前看primer的时候看到&有了一些理解,接着在平时使用的时候觉得自己有了更深的理解,发现书上讲得的确挺对但是却不怎么好理解,所以再写一篇来解释一下引用 & .大神勿喷,有错请指教,本人菜鸟一枚... 觉得在学习c++的时候 最重要的一个东西就是,你在学习的时候一定要搞懂它是什么? 那引用是什么呢? 其实呢引用 也是一个指针,哈哈. 为什么呢我们可以看一下 char a = 'a': char &b = a: b = 'b'; cout<<b: 代码会输出 字符

python 引用和对象理解

今天浏览博客的时候看到这么一句话: python中变量名和对象是分离的:最开始的时候是看到这句话的时候没有反应过来.决定具体搞清楚一下python中变量与对象之间的细节.(其实我感觉应该说 引用和对象分离 更为贴切) 从最开始的变量开始思考: 在python中,如果要使用一个变量,不需要提前进行声明,只需要在用的时候,给这个变量赋值即可 (这个和C语言等静态类型语言不同,和python为动态类型有关). 举第一个栗子: a = 1 这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利

php中引用&amp;的真正理解-变量引用、函数引用、对象引用

php的引用(就是在变量或者函数.对象等前面加上&符号) //最重要就是 删除引用的变量 ,只是引用的变量访问不了,但是内容并没有销毁 在PHP 中引用的意思是:不同的名字访问同一个变量内容. 变量的引用        PHP 的引用允许你用两个变量来指向同一个内容 <?php $a="ABC"; $b =&$a; echo $a;//这里输出:ABC echo $b;//这里输出:ABC $b="EFG"; echo $a;//这里$a的值变

解构委托、事件--我对他们本质的理解

一.委托 1.因为委托是一个特殊的类,所以定义委托和定义类一样,可以在命名空间下定义: namespace _06委托的理解 { public delegate void MyDeleget();//第一一个委托 public class MyClass { };//第一个类 } 2.委托可以看成是一个特殊的集合,所以委托也可以在类的内部定义: public class MyClass2 { public delegate void MyDelegat2();//委托也可以定义在类的内部 } 但

Java线程中断的本质深入理解(转)

一.Java中断的现象 首先,看看Thread类里的几个方法: public static boolean interrupted 测试当前线程是否已经中断.线程的中断状态 由该方法清除.换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外). public boolean isInterrupted() 测试线程是否已经中断.线程的中断状态 不受该方法的影响. public void in