如题,我同样使用一个对象给另一个对象赋值
发现在C#中两个对象被“关联”起来了
而在C++中却没有,似乎在c#中对象名是指针,而c++中对象名是内存的区域
这是我的疑惑,下面是我测试的代码,请大家分析一下using System;
using System.Collections.Generic;
using System.Text;namespace StructTest
{
class aa //测试用的类
{
public int a;
} class Program
{
static void Main(string[] args)
{
aa test1 = new aa();
aa test2 = new aa();
test1.a = 123;
test2.a = 456; Console.WriteLine("test1 " + test1.a);
Console.WriteLine("test2 " + test2.a);
test1 = test2;// 关键是此处
Console.WriteLine("test1 " + test1.a);
Console.WriteLine("test2 " + test2.a); test2.a = 789;// 给test2赋值,发现test1也变了
Console.WriteLine("test1 " + test1.a);
Console.WriteLine("test2 " + test2.a);
Console.ReadLine();
}
}}
// adfasdf.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include <afx.h>
#include <iostream>
using namespace std;class aa // 同样是测试用的类
{
public:
int a;};
int main(int argc, char* argv[])
{
int dddd;//没什么用就是让控制台程序停下来看结果 aa test1;
aa test2;
test1.a=123;
test2.a=456; cout<<"test1.a "<<test1.a<<endl;
cout<<"test2.a "<<test2.a<<endl; test1=test2; // 此处赋值 cout<<"test1.a "<<test1.a<<endl;
cout<<"test2.a "<<test2.a<<endl;
test2.a=789; // 对test2赋值,但是test1并没有跟着变
cout<<"test1.a "<<test1.a<<endl;
cout<<"test2.a "<<test2.a<<endl;
cin >> dddd;
return 0;
}
发现在C#中两个对象被“关联”起来了
而在C++中却没有,似乎在c#中对象名是指针,而c++中对象名是内存的区域
这是我的疑惑,下面是我测试的代码,请大家分析一下using System;
using System.Collections.Generic;
using System.Text;namespace StructTest
{
class aa //测试用的类
{
public int a;
} class Program
{
static void Main(string[] args)
{
aa test1 = new aa();
aa test2 = new aa();
test1.a = 123;
test2.a = 456; Console.WriteLine("test1 " + test1.a);
Console.WriteLine("test2 " + test2.a);
test1 = test2;// 关键是此处
Console.WriteLine("test1 " + test1.a);
Console.WriteLine("test2 " + test2.a); test2.a = 789;// 给test2赋值,发现test1也变了
Console.WriteLine("test1 " + test1.a);
Console.WriteLine("test2 " + test2.a);
Console.ReadLine();
}
}}
// adfasdf.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include <afx.h>
#include <iostream>
using namespace std;class aa // 同样是测试用的类
{
public:
int a;};
int main(int argc, char* argv[])
{
int dddd;//没什么用就是让控制台程序停下来看结果 aa test1;
aa test2;
test1.a=123;
test2.a=456; cout<<"test1.a "<<test1.a<<endl;
cout<<"test2.a "<<test2.a<<endl; test1=test2; // 此处赋值 cout<<"test1.a "<<test1.a<<endl;
cout<<"test2.a "<<test2.a<<endl;
test2.a=789; // 对test2赋值,但是test1并没有跟着变
cout<<"test1.a "<<test1.a<<endl;
cout<<"test2.a "<<test2.a<<endl;
cin >> dddd;
return 0;
}
对应到C#就是struct和class
一个引用类型的变量你可以看做是指向这个类型的一个指针.
例如:
Form frm = new Form();
里的frm你可以看做是指向一个窗体实例的指针(事实上是一个Handle).
引用类型实例的实际内存分配则是在托管堆中.而值类型不同,当你运行
Point pt=new Point();
时pt则是实实在在的在栈上开辟了sizeof (Point)大小的
空间.而运行
Point pt2 = pt;
则是把pt的内容完整的复制到pt2中而不是赋个指针了事.LZ有兴趣可以去啃啃CLI via C#或者CLI via C++/CLI
这就是为什么: test2.a = 789;// 给test2赋值,发现test1也变了 如果是两个Int类型的变量就不会了.
因为int是值类型,其是直接放置在堆栈上的两个不同的地方,不会再有引用地址指向到托管堆中.
所以,任意一个的改变只会影响自己.int i = 1;
int j = 100;
j = i; //此时 i = 1 , j = 1
j = 100; //此时 i = 1 , j = 1002.C\C++中: test1=test2;
个人对C\C++了解不多(VB转VB.NET,C#的),但原理应该差不多.
test1=test2; 实际上只是单纯的传值而已.就相当于把test2的值COPY到test1. 两个的值还是指向不同的地方.
而如果申明成这样就不同了,就会跟.NET一样aa *test1;
aa *test2;
ObjPtr:返回任何对象变量引用的地址
Private Sub Command1_Click()
Dim A As Class1, B As Class1, C As Class1
Set A = New Class1
Set B = New Class1
Set C = New Class1MsgBox ("A:" & VarPtr(A) & vbCrLf & _
"B:" & VarPtr(B) & vbCrLf & _
"C:" & VarPtr(C) & vbCrLf)
End Sub
(2)关于Set C= A 以及 SET C = NEW CLASS1的区别代码如下:
Option ExplicitPrivate Sub Command1_Click()
Dim A As Class1, B As Class1, C As Class1
Set A = New Class1
Set B = New Class1
Set C = AMsgBox ("A:" & VarPtr(A) & vbCrLf & _
"B:" & VarPtr(B) & vbCrLf & _
"C:" & VarPtr(C) & vbCrLf)MsgBox ("A:" & ObjPtr(A) & vbCrLf & _
"B:" & ObjPtr(B) & vbCrLf & _
"C:" & ObjPtr(C) & vbCrLf)
A.Value = 100
MsgBox ("C.Value:" & C.Value)
C.Value = 99
MsgBox ("A.Value:" & A.Value)Set C = BMsgBox ("A:" & VarPtr(A) & vbCrLf & _
"B:" & VarPtr(B) & vbCrLf & _
"C:" & VarPtr(C) & vbCrLf)MsgBox ("A:" & ObjPtr(A) & vbCrLf & _
"B:" & ObjPtr(B) & vbCrLf & _
"C:" & ObjPtr(C) & vbCrLf)
C.Value = 1
MsgBox ("A.Value:" & A.Value)
MsgBox ("B.Value:" & B.Value)
End Sub
把Class1也贴上 Option ExplicitPrivate value_ As IntegerProperty Get Value() As String
Value = value_
End PropertyProperty Let Value(ByVal NewValue As String)
value_ = NewValue
End Property