精华内容
下载资源
问答
  • 一个小问题老困扰着我:怎么给js引用类型变量赋值一个引用变量(变量给变量赋值),他们操作时独立的,不受影响。 这样?<script type="text/javascript"> var s={"a":"1","b":"2"}; var t=s; s={}; //...

      一个小问题老困扰着我:怎么给js引用类型变量赋值一个引用变量(变量给变量赋值),他们操作时独立的,不受影响。

    这样?

    <script type="text/javascript">
    
    	var s={"a":"1","b":"2"};
    	var t=s;
    	
    	s={};	//重新分配内存空间
    	
    	for(var p in t)
    	{
    		s[p]=t[p];
    	}
    	t.a="10";
    	s.a="20";
    	alert(s.a);
    	alert(t.a);
    </script>
     
    有更好的方法么?期待~!

    转载于:https://www.cnblogs.com/tedyding/archive/2010/06/02/1749659.html

    展开全文
  • 先讲变量在内存中的存储位置:值类型存储在栈中,引用类型存储在堆中,堆栈这里不明白也不影响,有个基本的概念就行了 先谈复制 int a = 5; int b = a; 这是值类型,存储在栈中,这个例子中变量b就复制了a,下面看...

    博客换到博客园了,这是我的新博客地址:https://www.cnblogs.com/wujuncheng
    欢迎前来踩踩

    先讲变量在内存中的存储位置:值类型存储在栈中,引用类型存储在堆中,堆栈这里不明白也不影响,有个基本的概念就行了

    先谈复制

    int a = 5;
    int b = a;
    

    这是值类型,存储在栈中,这个例子中变量b就复制了a,下面看引用类型

    Test t1 = new Test();
    Test t2 = t1;
    

    这时候t2和t1指向了同一个对象,为什么会这样呢,看看内存中是怎么表示的
    变量在内存中的表示
    第一步int a =5,先在栈中分配一个空间,假设地址(可以理解为门牌号)是0x00000001,在这个空间中存储了一个值5

    第二步int b=a,这也在栈中分配一个空间,假设地址是0x00000002,因为使用赋值运算符“=”,所以b的空间中存储的值是a的空间中的值的拷贝,这就是值类型的复制

    第三步Test t1 = new Test(),t1是一个引用类型的变量,引用类型的变量在内存中的存储就不一样了,这个语句其实是分两步执行的,首先执行new Test(),因为使用了new关键字,首先在堆中创建了一块内存空间,我们假设是0x10000001,这时候new Test()的部分执行完了,然后是将new Test()的执行结果赋值给Test类型的变量ti,这个过程是在栈中分配空间,假设地址是0x00001001,在这个空间中存储new Test()返回的堆空间地址。所以,一个引用类型的变量实际是经过了两次跳转的,程序先根据变量名对应的地址找到栈中的空间,再通过栈中空间存储的地址找到堆中的地址空间

    明白了这个过程,我们就很好理解为什么当t2=t1后操作t2时,t1的内容也会跟着变了

    第四步Test t2 = t1,这里只使用了赋值运算符创建了一个变量,所以在内存中的行为仅仅是单纯的在栈中分配一个空间,假设地址是0x00001002,然后将t1在栈中的空间的值拷贝过来,所以t2在栈中的空间存储的也是t1在堆中地址信息

    如果调用t2,那么其过程就是根据变量名对应的地址找到栈中的空间,然后栈中空间存储的是从t1那里复制过来的t1指向的堆地址,程序继续跳转到对应的堆地址

    t1和t2有不同的栈空间地址,但因为栈空间中存储的堆空间地址相同,经过跳转之后便相当于操作了同一块堆空间,所以无论是t1还是t2对相关内容进行改变,其对应的值都会跟着变

    展开全文
  • c++里给常量引用初始化赋值的... 如果给常量引用初始化赋值类型是一致的,那么编译的时候就不会生成临时量,这个时候不管怎么改变被引用的变量的值,通过引用输出的值都是被引用的值,而不是临时量。 举例如下...

        c++里给常量引用初始化赋值的类型不一致的时候,编译器会创建临时量,这个时候常量引用其实是引用的临时量,这个临时量我们是没法访问的。如果改变了被引用的变量的值,通过引用来输出的话还是输出原来的值(即临时量的值)。

        如果给常量引用初始化赋值的类型是一致的,那么编译的时候就不会生成临时量,这个时候不管怎么改变被引用的变量的值,通过引用输出的值都是被引用的值,而不是临时量。

    举例如下:

    c++中常量引用:const int &p=someval;

    当等号后面跟的是一个非int类型的基本类变量,编译器会创建临时量。比如:

    float someval=3.14159;
    
    const  int &p=someval;

     

    这个时候,编译器会如下操作给p赋值:

    const int tmp=3;
    
    const int &p=tmp;

    这个时候如果改变了someval的值,在通过p输出的时候不会是someval的值。

    someval=55.5555;
    cout<<p<<endl;   //输出还是为3

    完整测试程序:

    int main(int argc,char** argv){
    
    float someval=3.1415926;
    const int &p=someval;   // 在这里我用float类型赋值给整型的引用,触发临时变量产生,p是临时量。跟someval不在同一内存单元
    cout<<someval<<","<<p<<endl;  // 输出:3.1415926,3
    
    someval=5555.5555;
    cout<<someval<<","<<p<<endl;  //输出:5555.5555,3
    
    
    //下面测试类型一样的情况
    int goodval=1000;
    const int & pg=goodval;  //在这里两边赋值的类型是一致的,不会触发产生临时量,pg就是goodval,内存里是同一个内存单元。
    
    cout<<goodval<<","<<pg<<endl; //输出1000,1000
    
    goodval=999;   //这里改变goodval值,后面输出还是会一致
    cout<<goodval<<","<<pg<<endl;  //输出 999,999
    
    return 0;
    }

     

    展开全文
  • 1、首先来说一下java中引用类型对象是怎么赋值: java中对于引用类型的对象的赋值(即用“=”把他们两种相连)都是指针传递,即复制一个指针给另外一个对象,这两个对象大家都指向同一处堆内存空间(如果这个对象是...

    1、首先来说一下java中引用类型对象是怎么赋值:

    java中对于引用类型的对象的赋值(即用“=”把他们两种相连)都是指针传递,即复制一个指针给另外一个对象,这两个对象大家都指向同一处堆内存空间(如果这个对象是new的)即同一块地址。所以当前一个对象赋值为null后,后面那个对象同样可以指向之前的内容,丝毫没有影响。这个相当于c++对象之间的浅拷贝,即把指针也一块拷贝过去了。

    下面看一个简单的java的demo

    package indi.demo;
    
    public class Test {
    	
    	public static void main(String[] args) {
    		/*总结:java中对于引用类型的对象都是指针传递,即复制一个指针给另外一个对象,大家都指向同一处堆内存空间。
    		而c++若成员变量中含有指针的对象的赋值和“=”,是真正的复制,也就是说只是复制的内容,涉及到开辟内存空间的是就新开辟一个内存空间
    		来存储复制的内容,当然地址(指针)也就发生了变化,但是指向的内容相等,不能说相同,因为存储相等东西的存储地址变了。
    		为什么C++不像java那样呢,因为完全没必要啊,若真的想指向同一个内容(内存区域),完全传递指针或者引用就可以了啊,java中它是没指针的。
    		*/
    		Student s1=new Student("zhangsan","001",new Student("呵呵","002", null));
    		Student s2=null;
    		s2=s1;
    		s2.getStu().setName("呵呵1");
    		System.out.println(s1.getStu().getName());
    		s1=null;
    		System.out.println(s2.getStu().getName()+"s2");
    	}
    
    }

     

    2、再来了解下C++中成员变量含有指针的对象间的赋值:

    c++中成员变量含有指针的对象的赋值(即用“=”把他们相连),是真正的复制,也就是说只是复制的内容,涉及到需要开辟内存空间的就新开辟一个内存空间来存储复制的内容(这个需要在拷贝构造函数,或者=号操作符重载中进行操作,当然也需要在析构函数中delete掉该对象中自己新开辟的堆内存空间),因此地址(指针)也就发生了变化,但是指向的内容相等不能说相同,因为存储相等东西的存储地址变了(指针里面就是存的该存储空间的首地址)。

    问题:为什么C++不能像java那样直接赋值呢:两个同类对象间直接进行引用传递。答案是:如果对象内不含指针,也就是类中包含的数据元素全部在栈上,没在堆上,浅拷贝也是完全可以的,对象将完全和java一样直接赋值,和java唯一的区别是这个对象是在栈上,而java中new的对象是在堆上。但是,如果对象内部含有指针,也就是类中的数据元素有在堆内存上的,就不能像java那样只是用"="简单赋值了,还应该建立相应的拷贝构造函数和"='等号操作符重载函数,为存放在堆内存上的数据重新开辟空间,防止析构的时候重复删除对应指针出的内容,导致宕机。java它有自己的垃圾回收机制,会自动清理堆内存中的垃圾,而c++中一般是通过析构函数中delete或者手动delete。凡是指向堆内存的指针都不能delete掉两次,不然程序都会出错。所以c++中的“=”分两种情况,都在栈上时就是指针传递,含有堆内存数据时就是复制,java中除基本类型外都是指针传递。这儿需要明确一点,c++中通过new创建的数据都是存放在堆内存的,new返回的都是指向堆内存空间的指针,当然c语言中的malloc函数开辟的空间也是在堆内存上,与new相似,只是new与delete会调用构造和析构函数,所以c++中用new和delete,用new开辟的堆内存空间,一定要手动删除。

    这儿额外补充个知识:c++中用new和不用new创建对象的本质区别!

    1:作用域不同

    不用new:作用域限制在定义类对象的方法中,当方法结束时,类对象也被系统释放了,(安全不会造成内存系统泄漏)。

    用new:创建的是指向类对象的指针,作用域变成了全局,当程序结束时,必须用delete删除,系统不会自动释放,(不注意可能造成内存泄漏)。

    2:用new 是在堆内存上开辟空间,而不用new就是在栈上,相当于一个局部变量。

    下面给出一个c++成员变量含有指针的一个对象的demo:

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    using namespace std;
    
    
    class Student
    {
    private:
    	int id;
    	char *name;
    public:
    	Student() {
    		id = 0;
    		name = NULL;
    	}
    	//构造函数中,对于成员函数是指针的同样要开辟存储空间
    	Student(int id, char *name) {
    		this->id = id;
    		int len = strlen(name);
    		this->name = new char[len + 1];
    		strcpy(this->name, name);
    	}
    	//拷贝构造函数
    	Student(const Student &std) {
    		this->id = std.id;
    		//执行深拷贝
    		int len = strlen(std.name);
    		this->name = new char[len+1];
    		//将之前的name对应的字符串拷贝到现在新开辟的内存空间对应的name地址
    		strcpy(this->name, std.name);
    	}
    	//等号操作符重载
    	Student & operator=(const Student & std) {
    		//思路:成员变量中含有指针的对象赋值,必须考虑重新开辟一个存储空间,而且开辟之前要把自己指针所对应的空间销毁
    		//防止出现自身赋值
    		if (this->name == std.name) {
    			return *this;
    		}
    		//将指针之前对应的内存空间销毁
    		if (this->name != NULL) {
    			delete name;
    			name = NULL;
    			this->id = 0;
    		}
    		//开辟新的内存空间,用于复制想要拷贝的东西
    		this->id = std.id;
    		int len = strlen(std.name);
    		this->name = new char[len+1];
    		strcpy(name, std.name);
    	}
    	//析构函数,必须清理掉自身开辟的内存空间,c++只给你清理本身对象所对应的空间,而你自己开辟的对应指针的空间需自己销毁,
    	//而java什么都不用你操心
    	~Student() {
    		//判断name是否为空,不为空就清理掉它对应的内存空间,并将name赋值为空
    		if (name != NULL) {
    			//注意指针对应的若是数组,应该用delete[]!!!
    			delete[] name;
    			name = NULL;
    		}
    	}
    	int getId() {
    		return this->id;
    	}
    	const char * getName() {
    		return this->name;
    	}
    };
    int main() {
    	Student s1(1, "zhang3");
    	Student s2(2, "li4");
    	Student s3=s2;
    	cout << s1.getId() << "," << s1.getName() << endl;
    	//s3 = s2;
    	cout << s3.getId() << "," << s3.getName() << endl;
    }

     

    展开全文
  • 什么是赋值?什么是引用?​ 赋值使用的操作符=,...如果右边是一个对象,则是将对象的引用赋值给左边,即引用,其实两者之间并没有差别,在于我们怎么去理解。基本数据类型赋值public static voidmain(String[]...
  • 背景新语言Kotlin已经抛弃了Java里的基本数据类型,而是采用引用类型去声明一个变量,那么怎么区分基本数据类型和引用类型呢?文字概念基本数据类型:byte、short、int、long、float、double、char、boolean引用类型...
  • 1.数组定义数组是一种数据结构,是用来存储同一数据类型的有序集合,并可以...客户端程序员未赋值,JVM会自动赋值(int自动赋值0,boolean自动赋值false,引用类型自动赋值null)可以int [] a定义数组,也可以int a ...
  • Java基本数据类型和引用类型的区别

    千次阅读 2020-08-27 23:30:52
    类(class)、接口(interface)、数组(array)基本类型保存的值,引用类型保存了是对象的地址,所有基本类型赋值是按值传递(拷贝赋值),引用类型赋值是按引用传递。 图与代码解析 参考:知乎作者:Intopass 一:搞清楚...
  •   vue项目 ,定义了一个变量,然后 this.requirements 和 this.showRequirements 都赋值为 requ ,在 this.requirements ...因为数组是引用类型的数据,所以,当指向为同一个指针的时候,改变这个数组的值会...
  • Java虚拟机可以处理的类型有两种,一种是原始类型(Primitive Types),一种是引用类型(Reference Types).与之对应,也存在有原始值(Primitive Values)和引用值(Reference Values)两种类型的数值可用于变量赋值、参数...
  • 近期遇到了DateTime到底是值类型还是引用类型的疑惑,顺势较深入地了解一下DateTime相关的内容 结论:DateTime是值类型,因为DateTime是结构体,而结构体继承自System.ValueType,属于值类型 一、DateTime是值类型...
  • 新语言Kotlin已经抛弃了Java里的基本数据类型,而是采用引用类型去声明一个变量,那么怎么区分基本数据类型和引用类型呢? 文字概念 基本数据类型:byte、short、int、long、float、double、char、boolean 引用类型...
  • 在该方法中,我们首先声明了一个值类型变量ageInt,但并未给它赋值,接着声明了一个典型的引用类型变量 ageObject,并把ageInt赋给它,这里就进行了一次装箱操作。编译器现在托管堆上分配一块内存空间(空间大小为...
  • 1、 Class 实体是引用类型,但传入方法时是null的情况在子方法中不论怎么赋值当 FirstService.SetPerson(person,ref tempMsg); 执行后Person都是null;如图1和图2; 但当在 Index2 方法中为person 实例化后就可以...
  • python是一种动态类型语言,在赋值的执行中可以绑定不同类型的值,这个过程叫做变量赋值操作,赋值同时确定了变量类型。在python学习过程中会用到许多数据,那为了方便操作,需要把这些数据分别用一个简单的名字代表...
  • 这些内容是每一种编程语言的基础。...引用类型 最基本的定义:值类型-每个实例都拥有其数据的一份副本。当被赋值给一个变量或常量,或传递给一个函数时候,它会建立一份新的副本。 有需要关于iOS学习的视频与
  • 但是如果我问你“拷贝构造函数的参数为什么必须使用引用类型?”这个问题, 你会怎么回答? 原因: 如果拷贝构造函数中的参数不是一个引用,即形如CClass(const CClass c_class),那么就相当于采用了传值的方式...
  • 但是如果我问你“拷贝构造函数的参数为什么必须使用引用类型?”这个问题, 你会怎么回答? 或许你会回答为了减少一次内存拷贝? 很惭愧的是,我的第一感觉也是这么回答。不过还好,我思索一下以后,发现这个答案是...
  • 如同基本类型赋值语句一样,同一个类的对象之间也是可以进行赋值操作的,即将一个对象的值赋给另一个对象。 对于类对象的赋值,只会对类中的数据成员进行赋值,而不对成员函数赋值。 给对象赋值和调用拷贝构造函数...
  • 当方法调用时的参数为基本类型时可以打个比方: ( 我把我家有多少钱告诉你,...当调用方法的参数为引用类型时,可以打个比方, (我把我家的钱都交给你让你替我花,你花了多少我的钱就少了多少,你花的钱和我家的钱同属一个根
  • 本文来和大家来理解一下python中的赋值、深拷贝与浅拷贝。首先先来看几个概念:1....可变对象:可以改变的对象,比如列表,字典,集合1赋值在python中,对象赋值实际上就是传递引用。当创建一个对...
  • 在C++中, 构造函数,拷贝构造函数,析构函数和赋值函数(赋值... 但是如果我问你“拷贝构造函数的参数为什么必须使用引用类型?”这个问题, 你会怎么回答? 先从一个小例子开始: #include <iostream.h> c...
  • 先把答案说出来:拷贝构造函数参数(参数是本类类型时)之所以只能是引用类型,是为了避免调用时产生无限递归!如果你懂得,就崩往下看了。 在C++中, 构造函数,拷贝构造函数,析构函数和赋值函数(赋值运算符重载)...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 280
精华内容 112
关键字:

引用类型怎么赋值