`
shv283fi
  • 浏览: 15417 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

深入static_cast运算符

阅读更多

深入static_cast运算符
2011年03月29日
  学无止境,把这几年收藏的文章都晒出来,大家共享吧! 声明:早期转载的文章未标明转载敬请原谅,以后将陆续改过来,向原创者致敬! C++ , Direct3D, OpenGL, GPU,OGRE,OSG,STL, Lua, Python, MFC, Win32 (有问题可留言,部分网页看不到图片可网页另存为到本地再打开即可看到) 痞子龙3D编程 QQ技术交流群:32103634
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  本文下载地址:
  http://bbs.sjtu.edu.cn/file/Apple/1200681928238350 .pdf
  许可:
  http://creativecommons.org/licenses/by-nc-nd/2.5/c n
  作者:Robert Schmidt
  Microsoft Corporation
  2000年5月18日
  译者:高博
  http://www.gaobo.org
  feedback@gaobo.org
  依我数年在Usenet的C++新闻组的潜水经验来看,四个型别转换运算符:const_cast、dy
  namic_cast、reinterpret_cast和static_cast之间究竟关系如何一直是软件工程师的困
  扰之源。尤其是reinterpret_cast和static_cast的区别,对许多软件工程师而言十分模
  糊--或者不如说简直是视而不见。在以下的两讲里,我会演示一下两者之间的区别,
  并给出何时应该应用何者的指南。(译注:本文是讲了static_cast的第一讲。)
  概览
  顾名思义,static_casts将具有某种静态型别的表达式转换成具有另外某种静态型别的
  对象或值。如C++标准(§2.5.9/1-3)(译注:原文误写为5.2.9)所言:
  表达式static_cast(v)之结果就是将表达式v转换为型别T的结果。如果T是一个引用
  型别,则结果为一个左值。否则,结果是一个右值。在一个static_cast表达式内不可定
  义新的型别。static_cast运算符不会将表达式的常量性(constness)转换掉。
  ……
  能够显式地使用形如"static_cast(e)"的static_cast表达式来转换为型别T的表达
  式e必须满足:"T t(e);"对某个虚构的临时变量t是一个合式的声明。否则,static_c
  ast表达式将执行下面列出的转换之一:
  ……
  其它任何的型别转换都不能够显式地通过使用static_cast来实现。
  这就是说,允许使用static_cast的场合包括:
  .一个具有目标型别(转换后的型别)的对象能够直接以一个具有源型别(转换前的型
  别)的值来初始化,或者
  .此种转换符合某个标准§2.5.9中随后列举的例外情形之一(我随后会简要地一一说明
  之)。
  标准的§2.5.9还提及,static_cast运算符"不会将表达式的常量性转换掉"。标准实
  际是说static_cast不会卸除CV-饰词(译注:即常量性--constness,饰词const和挥
  发性--volatility,饰词volatile)。比如,static_cast运算符不可以把char 
  const *转换为char *,尽管它可以把char *转换为char const *。(如果你想要卸除CV
  -饰词的话,唯一合用的型别转换运算是const_cast。我会在下面的一个更广义的讨论"
  常量正确性"--const correctness的论文里作有关const_cast运算符的完整论述,此
  去略去不提。)
  例:
  现有声明:
  struct B{
  operator int();
  };
  struct D : B{
  };
  B b;
  float const f = 0;
  下面的型别转换:
  static_cast(&b); // 等价于"(void *) &b;"
  static_cast(b); // 等价于"(int) b;"和"int(b);"
  都是合式的。第一个型别转换依赖于一个标准支持的从B *到void *的隐式型别转换,而
  第二个则隐式调用了b.operator int()。两个型别转换都遵从了标准§2.5.9中描述的一
  般规则。但正如我刚才提到的,它还列出了一些一般规则不能涵盖的例外。这些例外使
  得以下的转换加入了被允许之列:
  static_cast(f); // 等价于"(int) f;"和"int(f);"
  static_cast(b); // 等价于"(D &) b;"
  尽管这些转换的目标型别对象是不能用源型别的值来初始化的。
  最后,看看这对表达式:
  static_cast(&f); // 没问题
  static_cast(&f); // 错误!
  第一个转换成功完成了,但第二个可耻地失败了。它们都企图把一个指涉到float的指针
  转换成一个指涉到int的指针,但是第二个转换把const饰词也转换掉了--这是标准大
  声禁止的。第二个转换如果在老旧的型别转换语法里就能够畅行无阻:
  (int *) &f; // 译注:没问题
  隐式型别转换
  标准的§2.5.9/1允许:
  T t = static_cast(e);
  当:
  T t(e);
  是合式的,亦即,直接的、无转型的初始化是可行的。这隐含了一层意思,就是声明:
  long l = static_cast('x');
  和
  long l('x');
  是等价的。你也许会对语言居然允许这样冗余的转型觉得古里古怪,就好像它们仅仅使
  源代码显得更加
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics