- 在线时间
- 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>( _3 o) C6 R+ H* ?* _0 a% u
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
+ f: i" U' V, ~, [+ U
0 a. u. \) ]$ X1 I y# Jclass C {
+ y$ ?8 ]( i: @! a5 z8 l3 T" v1 ]4 vint i;
, F9 c0 J) ?8 V* y3 P" F, ?//...' |8 g# q" c; O1 @
public:; W* T. F' K5 G4 x1 b" i3 s4 E
C(int i);//constructor and implicit conversion operator( v% ^7 V4 r E8 o4 \5 O% n
//as well# f& C* l& U+ \8 g
};/ z" \- Y$ }4 P+ z
3 p# e& t' `6 N( Uvoid f() {
, M; h% P4 z8 S9 i
1 y( A' `. k( q: u% }C c(0);+ M' V+ p4 V1 U
' ?2 s( i* W8 J9 o
c = 5; //将 5 隐式转换为 C 对象,然后赋值
/ d4 g3 A0 h+ f+ @6 d3 F
% @7 A" j* [$ Q4 s) A! T. U- `}
/ d9 F7 i g- y% z) J" M
6 a6 [. f* _0 N `3 U% @" R编译器重新编辑上述例子代码,如下: ' H; R6 m7 N+ \7 q6 p/ d
8 `: w. N* p8 E8 n4 q# e/ K5 n//////////////////////////////////////////////////////////////////////////////////////////
6 ]& [6 f, q( {8 g/ c//"c=5;" 被编译器转换成下面这个样子:2 C2 Z! s ?9 Q8 p# t9 Q$ f
/////////////////////////////////////////////////////////////////////////////////////////
0 F; B4 X7 P3 V( p
+ L% R/ A) V3 S% s, M$ kC temp(5);// 实例化一个临时对象,
# E1 I3 E) I; P% E7 w3 N- @" \c = temp; // 用 = 赋值
, ~5 K- l4 B$ P/ T4 o( itemp.C::~C(); // temp 的析构函数被激活* x/ G! Q5 V# D) @! D
# d j- O! c2 v1 \4 t0 v+ ]) p/ q在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
0 q6 O7 e0 U+ c- H: q9 z/ ` K, k0 i u, P9 D
class String {) v8 [/ P8 C- y1 C1 }$ ^ m
int size;* l2 k& ?! I8 c j+ B4 Z' s' k9 V
char *p;
; X# G1 g% {1 ~+ @3 e/ Z G. b0 R/ P//..
2 {5 g: M! j9 n6 o9 k3 @public:3 ?9 \8 V2 _8 d% a" I
String (int sz); //这里不希望进行隐式转换操作' z6 ]* ?0 g3 E `8 I- ~
};0 n; v. w" J1 \9 P. z" w) h
void f ()
/ `# U: J5 s7 q) A" a, Q8 B# a{: }+ K! H9 J5 C4 e1 c1 I! R
String s(10);3 Z+ h, A s0 \- A" w0 x- S5 D
/ Y. @! b" [. C5 B1 v# l // 下面是一个程序员的编码;发生一个意想不到的转换:
. _7 G4 ?4 |4 E
# m. W- S. x: P9 G6 m5 X: o; e s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
1 l+ l# D, K7 g! x$ k0 _} E! _+ A8 ~+ O! ^
4 e( ^% E: t% H$ B' d% i$ P
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
2 u2 n0 v2 y$ |8 V7 J0 o: t4 r- Y+ F3 ?' o7 t
class String {
9 l" P7 e8 A3 z% v4 X' |" lint size;" F6 K' t+ k7 m# M& g5 j( w; t
char *p;0 y1 r0 }; y0 s" d5 `
//..
; ?$ U! O0 Y, G' I9 Ppublic:
8 J1 X7 Q' }2 f // 不要隐式转换1 g! b; G; D$ l9 Q8 P, l2 V% Z
explicit String (int sz);
& U; R5 A7 z) n, @" U6 ?/ N- L% k* S String (const char *s, int size n = 0); // 隐式转换7 e5 m7 S* G1 m' d9 h
};
- Y$ @; X( s! \0 I% n+ e' y. A( q: v
void f ()( _( P2 ^6 _5 k# M3 M3 j
{$ g, e f6 F; m r+ i% s A! T# h! X
String s(10); v, X6 F% g: Y
. q3 p) _( E% B: _! r7 z6 ] s = 100; // 现在编译时出错;需要显式转换:/ d" r, l7 f) j3 @) E( f
$ }( b1 b8 j( O9 O R s = String(100); // 好;显式转换. f3 ] U6 }- x( ?3 x+ z
s = "st"; // 好;此时允许隐式转换
/ U: y, O0 T, ~, n" _( t} |
zan
|