关于C++强制类型转换操作结果的总结
上一篇 / 下一篇 2012-10-15 13:21:29 / 个人分类:C++
C++类型转换在刚学习C++不久就接触到的东西,由于那会儿对C++机制的不熟悉,并没有太多的疑问。随着对C++进一步的了解,基本类型转 换应该可以理解为生成了对应类型的临时变量。昨天看到了Effective C++条款3中,类的const与non-const重载函数,non-const函数调用const函数实现重载,即所谓的常量性转除(casting away constness)。示例程序代码如下:
UL!B4nSE0class CTextBox51Testing软件测试网 N9`W
S~ {51Testing软件测试网0vL3^YwO??/i public:51Testing软件测试网uWRh$u;g^z CTextBox(void);51Testing软件测试网 XV4S`fb CTextBox(char *szStr); .S!kF+s dIu)o0~CTextBox(void); FvgM r'ru0const char& operator[](std::size_t pos) const u8Ty/U%qx0{ return m_strText[pos]; } :m v%E ~%`r\a0char& operator[](std::size_t pos) ?/M|b4Ik.[0{51Testing软件测试网tQRx:M%}vN return const_cast<char&>((static_cast<const CTextBox&>(*this))[pos]); {0M ss*L(A^"L1Q"jb${0} ovH.rYCQ0private: n8\6K*J0Y%Ot9Z0std::string m_strText; J#M E\Ccs2k0}; |
操作符重载函数operator[]的non-const版本对this*做了类型转换,使其能够调用const版本的operator[]函数,如果 按照基本类型转换的临时变量理解,函数最后相当于返回了对临时变量的引用,这显然是错误的,而且不能达到程序员想要的目的。但是经过对代码的编译运行,发 现程序能够通过正确运行。所以产生了如下疑问:类型转换用于常量性移除时,是否针对原变量操作,而不是生成了变量;由此考虑类型转换的其他用途,比如对于 指针的转换等,是以何种方式进行的。下面引用神秘果的blog中关于C++类型转换的总结:
W \(\&w l];y"c J051Testing软件测试网cwqv]4Qan1EC风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:51Testing软件测试网M h2x!}.h)h"X;oa
51Testing软件测试网NhVI@L`ltTYPE b = (TYPE)a。
6dR/t]K051Testing软件测试网v})?j_9mN9BC++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。看似问题复杂化了,其实不然。C风格的类型转换在程序语句中难以识别,类型转换是 去const,还是int转换成char,或是子类指针转换成父类指针?C括号风格的强制类型转换解决不了这些问题。C++的4种类型转换能够解决这些问 题:51Testing软件测试网 aZJ G4S o"s;Z~0Ub
51Testing软件测试网/XW Z(kduq)G`const_cast,字面上理解就是去const属性。51Testing软件测试网*L;CfLr Y
1vWlEm%g0 static_cast,命名上理解是静态类型转换。如int转换成char。51Testing软件测试网#i{3S$x*g!Q#B
51Testing软件测试网/fHP6G-~,T.C]3CB gRdynamic_cast,命名上理解是动态类型转换。如子类和父类之间的多台类型转换。51Testing软件测试网*L6h9`;M3Tz,I:at
6c:X&~.lv,E2bQ0 reinterpreter_cast,仅仅重新解释类型,但没有进行二进制的转换。51Testing软件测试网KG4l%fV
F I+fo [[0 4种类型转换的格式,如:TYPE B = static_cast(TYPE)(a)。51Testing软件测试网i9M4o l(_W:[+bw
.X$@ cXp%_,r7d0 const_cast51Testing软件测试网 C2w}8zdo'}J
!G"Yw\O6Yw0 去掉类型的const或volatile属性。
*^P2ldf#w0struct SA {51Testing软件测试网u.L5cl;q#qv-K/]E}Bint i;51Testing软件测试网)I mac y#r)~m
};51Testing软件测试网,EnV D-n
const SA ra;
[8C4@Q*A4b9~0 //ra.i = 10; //直接修改const类型,编译错误51Testing软件测试网k6Bh7b Y5~:ch5`
SA &rb = const_cast<SA&>(ra);51Testing软件测试网!^'n!Z8i K6E|
rb.i = 10;51Testing软件测试网2d$Y'A)TEI7O
51Testing软件测试网%~m8@!M6CT_d2Ozc
static_cast
i-r4C2[X7h @#U;c9v1E8e07u7R&VZQ#X0 类似于C风格的强制转换。无条件转换,静态类型转换。用于:51Testing软件测试网n9j)o$t7ousD)O
:D~nI4|cd0 1、基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的。(基类和子类之间的动态类型转换建议用dynamic_cast)51Testing软件测试网1|)Xug)V xr/E)b}Y
qs So+EO0 2、基本数据类型转换。enum,struct,int,char,float等。static_cast不能进行无关类型(如非基类和子类)指针之间的转换。
!m|3vT)c s)H8gt051Testing软件测试网*u#\ w s`{oS6Pl~W3、把空指针转换成目标类型的空指针。51Testing软件测试网w6rW4cEP8m5~K%oLl
51Testing软件测试网XN^l H5h-{;N5t4、把任何类型的表达式转换成void类型。
1R-u#Cj[#wL%{+|\)g0"v h4z0@+|jS qF0 5、static_cast不能去掉类型的const、volitale属性(用const_cast)。51Testing软件测试网x7`;p%MyEp'?'^r
?(SY!ee#nTa0j051Testing软件测试网"Mb4JJ8O2L/o2I S
1intn=6; *U!yeRQ02 doubled=static_cast<double>(n);//基本类型转换51Testing软件测试网u5U7m {Ln 3 int*pn=&n;51Testing软件测试网.UV%s"H5dl9o 4double*d=static_cast<double*>(&n)//无关类型指针转换,编译错误 a8`*kk0bv,x;u6O05void*p=static_cast<void*>(pn);//任意类型转换成void类型 :u`'a)j)g]|c%?Co06 |
V"GK*v Wc0 dynamic_cast
Kt1hX0qfZMK h[051Testing软件测试网E.hp e6P7zh.q有条件转换,动态类型转换,运行时类型安全检查(转换失败返回NULL):51Testing软件测试网)\[n,p4Wu%k%T
51Testing软件测试网r7E @J%@'z4L{;x {[1、安全的基类和子类之间转换。51Testing软件测试网0r3b$Hi,I8w
51Testing软件测试网$yV"e'i.lEf6t#\2、必须要有虚函数。
X"U3n8^)TB8E&|051Testing软件测试网cqKlf5iV3~V3、相同基类不同子类之间的交叉转换。但结果是NULL。
8s*svm0B"KMI051Testing软件测试网}5dx-WS G U'@h,@Qw#z!~0class BaseClass {51Testing软件测试网(I7h;[B0txC public: %h4]G_;_8q;R0 int m_iNum;51Testing软件测试网NlwRg+` virtual void foo(){}; //基类必须有虚函数。保持多台特性才能使用dynamic_cast51Testing软件测试网0@jo&a/| n~0[7H#WO }; Q,a'd,c.M(~0 k d%t/? z:s0 class DerivedClass: public BaseClass { S3A/}C[!p-oS#W0 public:51Testing软件测试网8aYuX UEn2? char *m_szName[100]; ~HWz5k_V-Qs0 void bar(){}; W1_*sMbR;p;@q0 };51Testing软件测试网+OMa[X ?]v7M"[ 51Testing软件测试网g R8Qg5A"A$}7y Bn xg BaseClass* pb = new DerivedClass(); 0B{Ogx%k-z0 DerivedClass *pd1 = static_cast<DerivedClass *>(pb); //子类->父类,静态类型转换,正确但不推荐 4Y-ir o J0 DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb); //子类->父类,动态类型转换,正确51Testing软件测试网p i^;b"M A/_([m)W U5~#g s {[p0 BaseClass* pb2 = new BaseClass();51Testing软件测试网h:kgZ/cc-q DerivedClass *pd21 = static_cast<DerivedClass *>(pb2); //父类->子类,静态类型转换,危险!访问子类m_szName成员越界51Testing软件测试网 Ev;Z"o1s.vY DerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2); //父类->子类,动态类型转换,安全的。结果是NULL |
q9e]F*{6r0k0 reinterpret_cast
s-yz0t+a?Ux.~6J051Testing软件测试网+Cg&|6W-X9m@#C6n仅仅重新解释类型,但没有进行二进制的转换:51Testing软件测试网.PzBsHh
51Testing软件测试网)jt6sFl?0_1、转换的类型必须是一个指针、引用、算术类型、函数指针或者成员指针。51Testing软件测试网&p