- 在线时间
- 0 小时
- 最后登录
- 2005-9-21
- 注册时间
- 2004-4-27
- 听众数
- 1
- 收听数
- 0
- 能力
- 0 分
- 体力
- 1027 点
- 威望
- 0 点
- 阅读权限
- 40
- 积分
- 385
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 153
- 主题
- 43
- 精华
- 0
- 分享
- 0
- 好友
- 0
升级   28.33% 该用户从未签到
国际赛参赛者
 |
< align=center><FONT color=#0033ff><B>认识 C++ 中的 explicit 关键字</B></FONT>
* g: g. M( v+ j8 u3 F r; [( r(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:6 d9 |! j2 e/ x0 `0 W+ Y3 _$ {
3 w. t4 `0 w5 cclass C {
9 D) G5 w3 _9 r& ^int i;. U" X! {- O* a7 L! a) I
//...
/ r E. U+ Q) l( |2 jpublic:; W/ t* ^) z- ~: k* J' o
C(int i);//constructor and implicit conversion operator: D- u4 o. D/ h- L- G
//as well) P' M& D( s H" Q3 p6 W# ~
};- @/ a; V$ A |0 D6 }' X7 T% c* s# ?
4 J2 a, q0 x+ i, l
void f() {6 E) }0 |: t7 A: |/ x! l; r1 }
3 k9 w9 X3 w' l$ S' T, z
C c(0);$ ^( n( Y& ?4 C( w. p
2 l% O/ k/ A0 `- G1 j/ qc = 5; //将 5 隐式转换为 C 对象,然后赋值
# u0 P2 w/ c& j/ T* |& m# { S5 f f( k7 b9 i0 M3 n
}2 N' c5 @: c, F: v# {& T
, K% F7 c$ W' O* ^) X
编译器重新编辑上述例子代码,如下: : N d$ A: s' }7 T
' T; O0 S3 U2 c, e
//////////////////////////////////////////////////////////////////////////////////////////
9 ^3 g+ T6 v A- n# ~) q//"c=5;" 被编译器转换成下面这个样子:4 d2 v$ `. { h! C. q# k$ R4 L1 u8 L) k
/////////////////////////////////////////////////////////////////////////////////////////# u* q+ v6 E3 z
7 w0 p$ q% R5 G3 r% o: O6 |7 NC temp(5);// 实例化一个临时对象,7 j: W* ~, l* P7 p+ s- n; L
c = temp; // 用 = 赋值
1 N, Y j7 T$ \! ^temp.C::~C(); // temp 的析构函数被激活
8 @, C$ i/ k2 m- B. j* e9 u
: |- \$ C# l$ ]9 W' Z! D3 e在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:9 U7 I* A" [9 g( {6 l$ R: U
; o1 W' M6 s$ N& K' p
class String {5 U; h0 r2 X7 I, K; z: H
int size;
8 w! U4 C) h; I& H- ]( Ochar *p;( }! B, B* W& w' p& V
//..& T) c& u+ \! v7 Y) r$ s
public:" i B/ o' H& Q0 d/ `8 J% H
String (int sz); //这里不希望进行隐式转换操作+ `1 s3 @7 |8 x# w- f$ `
};2 o# D2 d" N( D% z3 ~9 c5 M: V
void f ()
`$ b1 h6 G* P: I# X7 @- P; X{4 [ y! d( b# a: g, H, v
String s(10);' }% A5 l1 w; v9 L9 J) D$ B! u1 [
( }0 q% ^# M7 B$ D
// 下面是一个程序员的编码;发生一个意想不到的转换:
0 _, w5 W0 H3 p" Z- f4 ~0 v5 M! q/ D7 L. S0 ^' @
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s0 `. K# d. \ c2 \! K) t3 o5 f
}
% c' o8 T( m N& N2 H: k w9 K7 N8 D6 b0 R
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
* f, K$ e7 ]8 C9 } w. W5 N$ _& |0 Y9 Q( r9 b" d
class String {; a o/ a2 D0 U& Q
int size;
- p }5 L4 W5 Y- I! k: rchar *p;, ^# x0 w; ?1 s, c$ t I
//..
& B8 H% l( L. j/ J$ n" vpublic:0 N x' R: e7 _1 s$ `: b! f
// 不要隐式转换
! W' e/ z( S, t. { explicit String (int sz); ' K; t* ?) R! {: O2 ^
String (const char *s, int size n = 0); // 隐式转换
; r, i/ l2 D) t+ u- x};. j' v9 w) v+ h" K, I
9 {- m; Y+ m, G9 s* d
void f ()
2 z7 x9 o) `/ \" F% x{- o8 e' s5 V0 X6 b
String s(10);
, C9 y2 q% v, F
& h1 }' A D4 s; J7 C, d s = 100; // 现在编译时出错;需要显式转换:
7 C. b. C6 D3 u+ c1 I% Z/ L) k( `. l1 q) M3 M' \
s = String(100); // 好;显式转换$ U0 Q9 _$ G2 {: z9 X4 }
s = "st"; // 好;此时允许隐式转换
& S b/ J: F& i1 G} |
zan
|