类型比较

数据类型可以看做两种:值类型和引用类型,由于他们类型不同,在不同的语言中对他们的处理方式也不一样,在其整个生命周期当中它们表现出不同的生命迹象。

 

1.       C#

类型分类:

A.值类型:

数值型(byte,unsigned byte,short,unsigned short, int,unsigned int,long,unsigned long,float,double,decimal)字符型(char)结构体(struct)枚举(enum

B.引用类型:

类(class),委托(delegate),事件(event),接口(interface)以及其他的非基本类型的数据结构。

表现行为:

A.        单纯的值类型的数据产生时,将会在运行栈上分配内存,具体大小因不同的数据类型和系统平台而不同,egint类型在xp0332位平台上会有4bytes的内存空间,long类型有8bytes的空间)

引用类型的创建发生在托管堆上,当我们声明className varname;时,首先会在堆栈上创建一个引用,只有当出现varname=new className();的时候,才会真正的在托管堆上分配内存空间,对于c#来说,一个对象的内存空间不仅仅时该对象所包含数据的大小的对应加和,每个对象含有额外的指针,大小分别位4bytes,例如method table的指针,以及同步指针等。

B.        当值类型的数据作为参数传递到方法中时,在内存中会产生该数据的copy,也就是说,进行值传递时,我们是对数据的复本进行操作,它的改变不影响原来数据的值。

当我们把引用类型作为参数进行传递时,其实我们传递的是对象的指针,它只是会在栈上重新创建一个指针对象,当我们对这个指针对象进行操作时,所有的改变都将影响到原对象。

C.        当一个引用对象中含有值类型的字段的时候,其内部的值类型的字段的空间也是分配在托管堆上的。

D.       String类型是一个特殊的引用类型,其原因时为了提高String类型的操作效率,编译器对string类型进行了优化。具体为:

String a=”this is first string !”;

String b=”this is second string !”;

String c=”this is first stirng !”;

当我们执行以上三条语句的时候,内存中其实只有两个字符串的值,也就是说ac指向内存同一个地方,而当他们其中一个发生改变的时候,另一个的值并不会发生改变。这就是字符串驻留机制的结果。

String a=”a”;

String b=”b”;

Sting c=”ab”;

String d=”a”+”b”;

此时dc同样是指向内存中同一块地址的,也就是说当某个字符串已经存在后,如果再有其他字符串变量,哪怕是这个变量是通过简单的字符串运算(字符串直接相加)得来的,那么他首先会在系统中的字符串表中寻找,如果这个字符串表存在该字符串那么就是分配个指针,否则分配内存。

E.当需要把值类型按照引用传递时,需要在类型前加ref或者out关键字;在调用方和被调用方该关键字都是必须的。Ref标记的关键字在进行传递之前必须进行初始化,out关键字在传出之前需要进行赋值操作。

2Java

类型分类:

A.值类型:

数值类型(byteshortintlongfloatdouble)字符类型(char)布尔类型(boolean

       B.引用类型:

类,接口,数组等除了8种基本类型之外的类型

表现行为:

       A----D.C#基本相同

              值与引用传递行为与c#同;eg

              class TestData

{

    public int a=4;

    }

class Change{

    public void changeInt(int a)

    {

       a=5;

    }

    public void changeRef(TestData td)

    {

       td.a=90;

    }

}

class PersonJ

{

    public static void main(String argsp[])

    {

           TestData td=new TestData();

           Change ch=new Change();

           int a=3;

           System.out.println(a);

           //值传递

           ch.changeInt(a);

           System.out.println(a);

           System.out.println(td.a);

           //引用传递

           ch.changeRef(td);

           System.out.println(td.a);

    }

}

 

       D表现行为示范,与C#同;eg

class PersonJ

{

    public static void main(String argsp[])

    {

       String a="abc";

       String b="abcd";

       String c="abc";

       String d=a+"d";db的内容虽相同却处于内存中的不同位置

       String e=a+b;

       String f=a+a+d;fe随内容相同内存地址却不同

       String g="ab"+"cd";gb内容相同内存地址也相同

       System.out.println(a+b+c);

    }

}

3.C++

数据分类:

AC++中所有的数据类型均为值类型:

Shortintlongfloatdoubleboolcharstructunionclass

表现行为:

A.所有的对象传递方式为按值传递方式,除非对参数加修饰关键字*&eg

#include <iostream.h>

 

class Person

{

private:

       int age;

public:

       void SetAge(int age){Person::age=age;}

       int GetAge()const;

};

 

int inline Person::GetAge() const

{

       return age;

}

void change(int a)

{

       a=3;

}

 

void change(int* a)

{

       *a=5;

}

 

void change(Person* p)

{

       p->SetAge(25);

}

 

void change(Person p)

{

       p.SetAge(111);

}

 

 

int main()

{

       Person p,q;

       p.SetAge(12);

       cout<<"p is "<<p.GetAge()<<endl;

       q=p;

       cout<<"q is "<<q.GetAge()<<endl;

       cout<<"p is "<<p.GetAge()<<endl;

       change(q);

       cout<<"p is "<<p.GetAge()<<endl;

       cout<<"q is "<<q.GetAge()<<endl;

       change(&q);

       cout<<"p is "<<p.GetAge()<<endl;

       cout<<"q is "<<q.GetAge()<<endl;

       int x=4;

       cout<<"x is "<<x<<endl;

       change(x);

       cout<<"x is "<<x<<endl;

       change(&x);

       cout<<"x is "<<x<<endl;

       int c;

       cin>>c;

      

       return 0;

}

 

 

注意:

       C++中类对象在向继承层次更高的类型传递时有切割问题存在。Eg

#include <iostream.h>

 

class Person

{

public:

       virtual void SetAge(){cout<<"Base class"<<endl;}

};

 

class Man:public Person

{

public:

       void SetAge(){cout<<"Child class"<<endl;}

};

 

void Dest(Person m)/*传子类造成子类特性的切除*/

{

       m.SetAge();

}

void Seco(Person* m)/*不会造成特性切除的传递方式*/

{

       m->SetAge();

}

void Thir(Person& m)

{

       m.SetAge();

}

 

int main()

{

       Man m;

       Person p;

       Dest(m);

       Dest(p);

       Seco(&p);

       Seco(&m);

       Thir(p);

       Thir(m);

       int c;

       cin>>c;

       return 0;

}

原创文章,转载请注明出处!
All CopyRight Reserved !

 

主页:http://jingtao.cnblogs.com

QQ:307073463
Email:jingtaodeemail@qq.com
MSN:sunjingtao@live.com

 

posted @ 2009-03-23 19:58  镜涛  阅读(1742)  评论(5编辑  收藏  举报
Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名孙镜涛(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言