细说C++类型转换操作符

上一篇 / 下一篇  2012-09-28 10:20:55 / 个人分类:C++

~+c2A.Q)nf)Z0  C++语言虽然兼容C,也支持C语言的类型转换用法,就是将类型用圆括号括起来,这种转换可视性比较差,难以跟踪错误的转换。C++提供了命名的强制转换操作符,毕竟转换有时是不安全的,所以使用命名转换操作符可以根据所使用的转换操作符可以判断风险级别。51Testing软件测试网%l7?[-C#mS

dd:P F^0  下面我们就来看看C++提供的四种命名的强制转换操作符的具体功能和用法。51Testing软件测试网;j B_H}1vY

51Testing软件测试网 Z%q.P@-n5ju5G?.c

  1、const_cast51Testing软件测试网9Mw;FK X O0{

w _-V0be0  2、static_cast51Testing软件测试网j4P/Wry%q+_

51Testing软件测试网"a"k5\/\'eN1I

  3、reinterpret_cast51Testing软件测试网3b.@8b8MGsxB!Ip

'Y'h k"E4s9?xZf.?7c5xD0  4、dynamic_cast51Testing软件测试网t$\)F*f0Z7b3[

,a[;uy o0  这四个操作符的使用方法是相同的,都是cast-name<Type>(expression),Type是被转换值expression的目标类型。51Testing软件测试网:N nt,u3z|'Yp,l

51Testing软件测试网:d'E y d5N(Q

  下面看看这四个操作符分别的应用场合。51Testing软件测试网&Zsw$R!\T])L

Ow)VzR0  1、const_cast51Testing软件测试网7yO+q-wfR[4H

51Testing软件测试网}[ I hfm8ln

  顾名思义,const_cast就是将表达式的const性质去掉,例如51Testing软件测试网z5E/J/_t o

J'K$MV M0

)r$FD&r4_PP X0
char* string_copy(char* s)
:T$EN(d4zR%kB0{
E.Hh1|+X)c;m0 return s;
#qed,s6U _M0}51Testing软件测试网*Nn%b:nC$W:Iv C
int main()51Testing软件测试网 EN(o$J%k(r
{51Testing软件测试网!DvEa5H v,M]
 const char* pc_str;51Testing软件测试网vub Gg
 char* pc = string_copy(const_cast<char*>(pc_str));//如直接传入pc_str则编译错误
m_L _Q^?j0 return 0;51Testing软件测试网 f PzEK(_
}
51Testing软件测试网[6\sE qYt

  上例只是说明问题,并不实现功能。51Testing软件测试网,vv6JNN&yUx

51Testing软件测试网 V!r ]JP9m0_

  要记住,const_cast只能用来添加或删除const特性,同时添加或删除特性也只能用const_cast。

9F7ZZ#hlcZ8AM0 51Testing软件测试网;h2w Ada'pF

  2、static_cast

'V'{dE._-]9s4s0 51Testing软件测试网9|5g4A%^7WPT

  这个用途比较广泛,编译器隐式执行的任何类型转换都可以有static_cast完成。51Testing软件测试网8w-s:XpGK9_

51Testing软件测试网W DO ?w8sW

  另外,static_cast多用于将一个void*类型的指针强制转换为原来的指针类型,例如:

qiw fPnj.Vc%C|0

n+C7V wE6K Y0 51Testing软件测试网?7|Y,MK @

 double d = 12;51Testing软件测试网1t'zT,tn:b^~ w
 void* p = &d;51Testing软件测试网5t^:aq-t
 double* pd = static_cast<double*>(p);
3H`w+e g.yU{v0 cout << *pd << endl;
51Testing软件测试网YL3ZB#[]5Jo$R

  输出结果为12,说明转换后依然还是指向同一个地址。51Testing软件测试网(p}*BH!{C+j,Ln}

$`6^Mf_0b Or1a0  3、reinterpret_cast51Testing软件测试网(BoGS k9oH7x

4g,Y!{8n,o:yj ?0  这个操作符很难看,也很难记,为什么呢,因为危险性比较大,设计成这个样子就是为了让我们尽量不用它,它用于对指针之间进行转换,例如:

7l)^3gew uD6x ?0 51Testing软件测试网 TST K5B/] e&A&[

+}W f/L:r1^)m6Q0
 int* ip;
K!T9yH)sIa0 char* pc = reinterpret_cast<char*>(ip);51Testing软件测试网8@ B ~d,}?!jQ
 string str(pc);
51Testing软件测试网_9X9N0fUdy.g

  虽然可以编译通过,但是却会带来严重的运行时错误,所以,要尽量避免reinterpret_cast的使用。51Testing软件测试网ZPpTGM

51Testing软件测试网 l2X2{%Cou

  4、dynamic_cast

2@+o;vI(azm(HGQt {0

'H4h[F;P[M"h'z0  dynamic_cast用于子类和父类之间的转换,它可以将父类的指针或引用转换为子类的指针或引用。51Testing软件测试网+z sM h%p#G{^&I4E

NS;?Jc4{*r0  dynamic_cast与前三种强制转换不同,它涉及运行时类型检查。如果绑定到引用或指针的类型对象不是目标类型的对象时,则 dynamic_cast失败。当用于指针的转换失败时,dynamic_cast的结果为0,用于引用的转换失败时,则抛出一个bad_cast异常。51Testing软件测试网;T8trm.L"^:Q q d-t

8H)r*B*n,V {;^Ly3G0  可用下面例子所用的结构对转换进行检测:51Testing软件测试网e^;S2|0S5A;kK

51Testing软件测试网/\,j*hkU;v

  指针转换:51Testing软件测试网C/B"Sc8r8JVO*]

+^8L)?g2ld _]H'@0

0x p4U-^j \:lZ0
 if(Derived *derviedPtr = dynamic_cast<Derived*>(basePtr){
bq8` KI"m9y wyq0  // use the Derived object to which derivedPtr points
E!eQbc%QU}*r0 }51Testing软件测试网D8alD9ilC;o
 else{51Testing软件测试网 sg5Vo~/z,O.Jzv
  // basePtr oiubsts at a Base object
fT`0xR:G|`Z0  // use the Base object to which basePtr points
3|"?6lsTUQZ J0 }

c`&t4L,R N B/P0  引用转换:

5B-TB)b3ttQ |0 51Testing软件测试网1O6}+IGk7Y

"`%YuJZ)i]0
 void f(const Base& b)
)?yC1ga|Iq0 {
~8~v({ E$z)TcyI)i0  try{
0V:Q4Q,K9~.J^#M0   const Derived& d = dynamic_cast<const Derived&>(b);51Testing软件测试网`O~-rSr6J+J
   // use the Derived object to which b referred51Testing软件测试网G!RZ4o,t{H!Y:@ r
  }51Testing软件测试网@*R1_-@F%oJ
  catch (bad_cast){
+jI a"A#vbM:x%\s0   // handle the fact that the cast failed51Testing软件测试网7Gwct8Y"a-L
  }51Testing软件测试网2W~ }#@~U i
 }

|.^@k ~ |d.B0  至此,转换操作符介绍完毕。51Testing软件测试网L \lMS4|!WL


TAG:

 

评分:0

我来说两句

Open Toolbar