- 在线时间
- 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>! D8 J2 B, `: h) z8 H2 }
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:+ A8 I7 ~* q4 j# X6 b, N* I/ P6 J
$ c, K0 Q7 v; N# T% Y- n
class C {" f0 n1 b. [0 O; }6 R0 d; c
int i;
s9 _" \* s& N* A; |//...
4 P7 W# K- ~5 ]- Wpublic:; ^3 Q' F& r9 L7 {( j
C(int i);//constructor and implicit conversion operator* D9 Q9 p; B5 B- w8 c. {
//as well
) n! a5 d1 \- Q6 c0 H5 C};# m1 K; Q" Y# @4 Q4 v1 _7 b
- ]0 \7 w, r {( I; c0 K1 Rvoid f() {
7 U3 S, f1 B, W9 f! m+ f* |1 }
C c(0);
: J0 @2 A V8 g0 T% \! a
& P$ e' H6 x" _. p" Zc = 5; //将 5 隐式转换为 C 对象,然后赋值6 z, S! q# |; x" u% b5 G6 ~
' q0 E$ a& P$ L- h* M5 M$ _
}
, ^# a/ p: K3 G3 S+ U. S; S5 Q% L3 C; L' T* _$ w
编译器重新编辑上述例子代码,如下: - Z. Y8 c0 o/ T1 ~! u
' u3 x5 `! z2 R( J6 O
//////////////////////////////////////////////////////////////////////////////////////////
& v* `9 ^" b4 d, p# r//"c=5;" 被编译器转换成下面这个样子:
! V6 i" ~3 H2 D/ v s- A; }9 l/////////////////////////////////////////////////////////////////////////////////////////
% u8 D- o" K6 e5 M+ b4 [
# a- G& ~0 ]+ ^* i/ @C temp(5);// 实例化一个临时对象,
: \6 b. d0 s2 g6 {9 zc = temp; // 用 = 赋值
1 _# l$ i* F- U" Y& Etemp.C::~C(); // temp 的析构函数被激活% u! o$ R8 j4 ~) N3 A
; i7 ^5 C H9 M. a在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
$ a/ O' x0 p7 H/ L1 l
. F3 j( T/ q- T6 p* M; t- \4 Kclass String {
; i8 R( w* p6 u% F7 ^; Yint size;2 s- A. D* x9 Y2 D' A5 R% |
char *p;
4 l6 O j, T) u" e" ]$ M//..
! q; a" k+ G8 r- Y. Apublic:$ Q" L, G- N X R w; o, r! ?
String (int sz); //这里不希望进行隐式转换操作: g/ R) A2 w; c; B- ?: Q( f. x# g: @
};
/ f: k6 t8 s7 r3 n% z" N1 H: Svoid f ()
' N0 g2 C; \, o6 n" ~: W0 B{3 Y) _( g& \, ^* J& w
String s(10);
% B) b: { `0 _4 k/ n; R L: ^9 a( g9 n+ P0 H- V
// 下面是一个程序员的编码;发生一个意想不到的转换:; L- Z3 U* F8 S
' g( V1 `; O8 ]7 _+ R
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s9 q6 l. Q2 W( K
} ) Q( ^: e8 n# Y# h
) q: V. ^0 i' n) u为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:3 T/ Z. I$ O+ w# T/ J$ I9 @6 C
5 c$ I2 ^) U3 y
class String {5 I5 d/ ^- P' a& _5 K
int size;- l6 _5 l1 |; o7 E2 V r
char *p;
$ }6 J% P0 r( @+ R" C6 M0 ?//..
: \% P! P0 E& z. Xpublic: v' z) m5 f- a9 c& s* D _9 w) `
// 不要隐式转换
& _8 X! y/ [5 k' Y; K4 J4 O: ^ explicit String (int sz); ' g p2 b8 ^: a; L$ ~
String (const char *s, int size n = 0); // 隐式转换
4 o$ K+ O0 y. M- }* ~% o* R! k9 L};' H: ]4 E( ?' |' k4 m
0 {2 O4 d) M; L# L
void f ()
1 a/ d( ?9 l F' j{; P- s% h; y' ^1 Q. ^' s
String s(10);
" I5 A' H2 S% @+ ^2 `$ X7 n c5 R- T# g" A
s = 100; // 现在编译时出错;需要显式转换:
) ?1 a' v& ]+ x z& W/ q& `: i" X' Y& z4 S. ^
s = String(100); // 好;显式转换! B" l0 @1 u+ M0 q3 [
s = "st"; // 好;此时允许隐式转换5 V: Y* _5 O2 @& |; r9 X$ k* `+ D
} |
zan
|