注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

数据挖掘

学习数据挖掘

 
 
 

日志

 
 

C++标准转换运算符static_cast  

2012-04-19 21:04:53|  分类: C++基本技巧 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
原文地址:

static_cast <new_type> (expression)

虽然const_cast是用来去除变量的const限定,但是static_cast却不是用来去除变量的static引用。其实这是很容易理解的,static决定的是一个变量的作用域和生命周期,比如:在一个文件中将变量定义为static,则说明这个变量只能在本Package中使用;在方法中定义一个static变量,该变量在程序开始存在直到程序结束;类中定义一个static成员,该成员随类的第一个对象出现时出现,并且可以被该类的所有对象所使用。

对static限定的改变必然会造成范围性的影响,而const限定的只是变量或对象自身。但无论是哪一个限定,它们都是在变量一出生(完成编译的时候)就决定了变量的特性,所以实际上都是不容许改变的。这点在const_cast那部分就已经有体现出来。

static_cast和reinterpret_cast一样,在面对const的时候都无能为力:两者都不能去除const限定。两者也存在的很多的不同,比如static_cast不仅可以用在指针和引用上,还可以用在基础数据和对象上;前面提到过reinterpret_cast可以用在"没有关系"的类型之间,而用static_cast来处理的转换就需要两者具有"一定的关系"了。

还是用例子来说明比较直观一些。

还是用例子来说明比较直观一些。

reinterpret_cast一篇,已经提到过reinterpret_cast可以在任意指针之间进行互相转换,即使这些指针所指的内容是毫无关系的,也就是说一下语句,编译器是不会报错的,但是对于程序来说也是毫无意义可言的,只会造成程序崩溃:

 #include <iostream> using namespace std; unsigned short Hash( void *p ) {  unsigned long val = reinterpret_cast<unsigned long>( p );  return ( unsigned short )( val ^ (val >> 16)); }  class Something {  /* Some codes here */ };  class Otherthing {  /* Some codes here */ };  int main() {    typedef unsigned short (*FuncPointer)( void *) ;  FuncPointer fp = Hash; //right, this is what we want   int a[10];  const int* ch = a; //right, array is just like pointer  char chArray[4] = {'a','b','c','d'};  fp = reinterpret_cast<FuncPointer> (ch); //no error, but does not make sense  ch = reinterpret_cast<int*> (chArray); //no error    cout <<hex<< *ch; //output: 64636261 //it really reinterpret the pointer     Something * st = new Something();  Otherthing * ot = reinterpret_cast<Otherthing*> (st); //cast between objects with on relationship }  

而以上转换,都是static_cast所不能完成的任务,也就是说把上边程序里所有的reinterpret_cast换成static_cast的话,就会立即得到编译错误,因为目标指针和原始指针之间不存在"关系"

从上边的程序,也就一下子看出来了reinterpret_cast和static_cast之间最本质的区别。

而以上转换,都是static_cast所不能完成的任务,也就是说把上边程序里所有的reinterpret_cast换成static_cast的话,就会立即得到编译错误,因为目标指针和原始指针之间不存在"关系"

从上边的程序,也就一下子看出来了reinterpret_cast和static_cast之间最本质的区别。

对于static_cast所需要的关系,"继承"绝对是其中之一,所以static_cast支持指向基类的指针和指向子类的指针之间的互相转换:

 class Parents { public:  virtual ~Parents(){}  /*codes here*/ };  class Children : public Parents {  /*codes here*/ };  int main()  {   Children * daughter = new Children();  Parents * mother = static_cast<Parents*> (daughter); //right, cast with polymorphism    Parents * father = new Parents();  Children * son = static_cast<Children*> (father); //no error, but not safe }  

但是从基类到子类的转换,用static_cast并不是安全的,具体的问题会在dynamic_cast一篇阐述。

在指针和引用方便,似乎也只有继承关系是可以被static_cast接受的,其他情况的指针和引用转换都会被static_cast直接扔出编译错误,而这层关系上的转换又几乎都可以被dynamic_cast所代替。这样看起来static_cast运算符的作用就太小了。

实际上static_cast真正用处并不在指针和引用上,而在基础类型和对象的转换上 。 而基于基础类型和对象的转换都是其他三个转换运算符所办不到的。

这些转换跟C++用户自定义类型转换一文中所设计的内容比较接近,所以在那边文章中出现转换可以全部加上static_cast。

基础类型转换:
float floatValue = 21.7;
int intValue = 7;

cout << floatValue / 7 << "\t\t" << static_cast<int> (floatValue)/7 <<endl;
cout << intValue/3 << "\t\t" << static_cast<double> (intValue)/3 << endl;

//Output:
//3.1     3
//2       2.33333

从输出结果可以看出转换是成功并且正确的。

对于对象的转换,也是需要又关系的,这层关系就是C++用户自定义类型转换中提到的方法:

  • 构造函数(Constructor)
  • 类型转换运算符(Type –Cast Operator

static_cast会根据上述顺序寻找到合适的方法进行类型转换。

赋值运算符并不被算在内,因为它自身已经是一种运算符,不能再当做转换运算符来用。

 int main(void)  {  Ape a;   Human h = static_cast<Human> (a); // using promtion constructor   Programmer p;  p = static_cast<Programmer> (h); // using  Programmer-cast operaotor   //Ape a2;  //a2 = static_cast<Ape> (p); //Error, assignment operator should be used directly   return 0; }  

(类的代码见C++用户自定义类型转换,或者下载代码查看)

传统转换方式实现static_cast运算符

从上边对static_cast分析可以跟看,static_cast跟传统转换方式几乎是一致的,所以只要将static_cast和圆括号去掉,再将尖括号改成圆括号就变成了传统的显示转换方式。在C++用户自定义类型转换一文已有很多的介绍了。


  评论这张
 
阅读(111)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017