`
lovnet
  • 浏览: 6705030 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

C++与C#对比:强制类型转换

 
阅读更多

强类型与弱类型语言

像C++,C,Java,C#这些主流的编程语言都是强类型语言.而一些脚本语言则是弱类型的,比如vbscript , javascript.

1.型语言简单的理解就是当定义了一个变量之后就会指定一个固定的类型,并对应一个固定的内存块大小.比如有int , double ,long这一个个的类型.并且一旦一个变量被指定为某个类型后就不能被当成其他类型用.除非做转换

在C++中我们经常看到int ,long之类的数值类型之间貌似可以互相通用.实际上是编译器按照实际情况给你隐式的做了下转换.而如果你把指针类型赋值给整数类型的话不符合通常的习惯,所以编译器就不给转了,直接报错.

2.型语言可以简单的理解成没有划分成int,float,char这多么类别.根本没类型的概念.以前我们数学中用变量x,y一样,它就相当于一个代表符号,占位符一样,可以表示任何类型.像javascrip中我们在任何变量前简单的加个var就行.比如var pos = 123; pos = "I change"; 有些脚本语言干脆就不需要用var这样的东东来指定,直接 x = 3.14; y = "i am god"; 随便整个标识符放等号左边就是变量了.这样做基于的原理是所有数据在内存中无非都是表示成0101,我想怎么去解释这些01就怎么翻译,才不用你编译器来限制我啊.不过实际上要完全没类型的概念也不行,比如a = 1 + "3";怎么去辨别3是当成数字还是字符串.所以弱类型语言背后的解释器肯定会去做些类别判断,做些转换的.只是我们用起来看不到而已了.

弱类型语言使用起来非常灵活,方便.但如果代码一多肯定容易出错.而强类型虽然没那和灵活,但类型安全了嘛.不容易出错.而且编译器也会做类型检查,在编译期间发现一些类型使用不当的地方就给你报错.

弱类型语言由于根本没区分那么多类型.所以自然不存在啥类型转换.强类型语言为了不完全丢掉弱类型语言的灵活性,也允许不同类型之间做些转换.有时会隐式的转换.但最好还是尽量强制的去转换好点.

隐式转换

在隐式类型转换中,C++的判断条件松一点,几乎所有的数值类型之间都可以给你隐式转换了.比如int ,float , char之间都可以互相转,不会去检查啥值溢出或精度损失.而C#隐式转换条件严格很多.只有当没有值溢出且没有精度损失时才给转,不然报错.

比如double dd = 12.12;

int num = dd; //把dd隐式转换成int类型

这在c++中可以正常转换.但在C#中会报错的.C#中必须要自己去显式转换才行.

强制类型转换(显式转换)

强制类型转换和显式类型转换是一会事,文字游戏,说法不一样而已.

旧式的强制类型转换

C语言中的类型转换方式很简单.例如所float转换成int就是这样

double dd= 12.12;

int num = (int) dd; //或者int num =int(dd);

反正就在某个变量前加个类型名,然后用括号括下就可以了.

C++中继续兼容了C的用法.但C#只沿用了上面两种用法的前一种,就是int num = (int) dd;但int num = int(dd)这种用法没有再沿用,如果你这样用了编译器会报错的.

旧式用法虽然简单方便,但也有些缺点,比如如果是一连串的表达式中,有很多个括号,这样就不容易看出是类型转换了,可视性较差.而且没有错误处理机制.于是C++和C#都弄出了新的转换方法.

新式强制类型转换方式

C++中有static_cast , dynamic_cast, const_cast, 和reinterpret_cast四种转换方式.

你可能初次瞧到这么多关键字,而且长得这长丑一个,肯定看得非常不顺眼,会觉得还是C语言中加个括号简单方便美观多了. C++这四种转换方式有一个说法(当然真实性我还不确定)是其实是故意弄的样子这么丑而且是4个这么多,目的就是为了让你用的不方便,最后都不想去用.因为强类型语言之所以整出那么多类型出来就是为了让你老实的按规矩用,别闲着没事转来转去.除非特殊情况非用不可才去转换.

1.const_cast

这个转换方式的功能只有一个,就是把const类型转换成非const类型.这种转换只能用这一种方法,其他三种方法用来干事就会出错.

你可能糊涂了,我们定义const的目的就是为了不让修饰那变量,怎么又要转成非const的了.大部分时候我们自然不会闲得蛋痛去做这样的转换,只有一些特殊情况会用到.比如你有这样的指针const char* pc = "arwen";

但是有个函数非要你转个char* 参数进去.比如Fun(char* pc),于是没辙啊,只能把转成非const.于是就这样转

Fun( const_cast<char*> (pc) );

当然了实际上你要用老式的方法也一样达到目的Fun ( (char*) pc );

2.reinterpret_cast

它一般用来转换不同类型的指针转换,或者在指针和数值之间转换.例如

int num = 123;

int* pNum = &num;

char* pChar = "weiwen";

pNum = reinterpret_cast<int*>( pChar); //把char指针转换成int*.

int no = reinterpret_cast<int> (pChar); //把指针转换成整数数字

char* pc = reinterpret_cast<char*> (no); //把数字转换成char*指针

当然上面的所有转换也可以用老方法 比如(int*) pChar, (int)pChar这样,简单的用个括号就行. 完全等价的.

3.dynamic_cast

一般用于继承间类型的转换.假如类Son 继承自Father;

Fun(Father* fa)

{

Son* so = dynamic_cast<Son*>( fa );

}

当然如果Father和Son没有继承关系的话,转换的结果就是so得到一个null指针.

同样可以用老方法Son* so = (Son*) fa;但这样如果转不了会报错.

4.static_cast

这种用法是最简单也最容易理解的,因为隐式转换时实际上都调用的它.所以一般认为合理的转换就用它,比如各种数值之间转换.而不合理的转换比如要把char* 类型转换成int*就会出错.同样也可以用老式方法替代了

C#强制类型转换

C#中有个关键字as,如果转换不成功就返回null;这主要用于自定义类型,各种对象之间的转换

比如 Son so = fa as Son;

另外内置类型的转换一般用函数Convert

比如有float类型ff.转成int型

int num = Convert.ToInt32(ff);

如果是把string类型转换成数值类型可用函数Parse

比如int num = int.Parse("123");

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics