- 在线时间
- 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>
- d0 g, m5 x6 @# j) X) A(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:2 ^! N4 H! v8 J8 T1 w$ W% c
8 z2 M$ e5 z* F
class C {
; M3 r( M' x: X; q$ D! Z2 uint i;
& i5 @) d0 ?8 v8 Y3 N//...
2 b- |5 z& C9 S* T. k0 p. J+ v0 _public:
) Y0 T% ?8 M- a [, T C(int i);//constructor and implicit conversion operator( }7 F2 G3 w6 I* f. u
//as well0 @* `/ z3 h! A3 k" o5 l
};
& y p1 L) m& D1 r- w
$ f7 {0 P \" B+ m8 Nvoid f() {* `! n$ v# m) J! q& S- @
/ D* C) A( g `9 v5 ], ~+ c4 \, f& @
C c(0);
- G" w, c6 @, X* |0 B3 Y
5 |: x7 ~% T( Q. B8 T( X) A' j/ ^8 hc = 5; //将 5 隐式转换为 C 对象,然后赋值0 k w; U# e& M9 ]) r
! i. y% |' L# s$ _% z' M}
3 H5 u" l b9 p9 G7 {+ D- v$ A9 X6 q2 ]
编译器重新编辑上述例子代码,如下: ( S4 z- x. k! h! O
0 @, I2 A6 l( [# R
//////////////////////////////////////////////////////////////////////////////////////////) a" t$ z& R/ w5 K Y$ x
//"c=5;" 被编译器转换成下面这个样子:
6 S3 a8 F/ Y9 r" B% ~- O/////////////////////////////////////////////////////////////////////////////////////////( E6 x( Q& M2 A
' N% |& A, m* E: x, n0 W% R8 JC temp(5);// 实例化一个临时对象,
c: Y+ z9 w- x/ d# lc = temp; // 用 = 赋值
$ L, r4 F5 `& D" O& s! s& U: ~ s, ptemp.C::~C(); // temp 的析构函数被激活
, U+ H. ^9 r( z1 H
# ]# ^- X0 z @" |在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
; o( b$ A4 y1 q9 u
; j; ?+ s& {# d" f) B1 I8 cclass String {, b0 Y- V% x4 L& b" n) t3 c8 Q |
int size;
9 C7 S+ R' c! z1 Z$ g. ~; r% kchar *p;. Y/ [7 K3 x6 Z( ^+ k* Y
//.." ^) {3 j; b3 `* a3 ~
public:2 s" Z! @, r9 @$ b1 z% i4 p
String (int sz); //这里不希望进行隐式转换操作
$ o) u$ I1 P# k2 s5 t/ N7 t; [};1 R$ N, V6 F& O! @/ n, e1 a
void f ()
7 P$ p7 C9 W) m# Z/ b, i5 g, m{
& M" Z8 Y( c% N2 ]% i String s(10);8 U' \: k+ u1 H% }. h8 L; }" e1 C
$ m0 h5 @- P' s. y# S // 下面是一个程序员的编码;发生一个意想不到的转换:5 l5 H5 W# F5 U! T$ S2 i
% N8 z9 P9 ~' n: Z, l s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
7 M9 d) N. n& ]# l3 w1 h z}
5 [ t* b! x1 d1 B! p
% o% t6 P" W3 S$ e& _为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
4 L0 a( c1 N( I
9 ^; _$ E# R( s+ Iclass String {
* x8 n8 B$ c" f+ V# S8 R8 pint size;0 b6 h4 b( c) v7 e: F' y
char *p;3 n4 U+ H; r/ w! e
//..
2 N& Z5 t2 D, P$ fpublic:
! I& L4 l' x) ` // 不要隐式转换
" A/ z, h9 [. b' _$ a explicit String (int sz);
1 p5 c# t) I" H& O% \3 q String (const char *s, int size n = 0); // 隐式转换
6 O1 u2 `3 w) @6 n};5 R" W2 q0 K* J
; C* ^$ v+ w# X# ^+ c T. x) T. yvoid f () r5 R; f5 X- B/ L# k9 N) l
{0 ]6 B" z, R5 Y8 c4 `
String s(10);
( Q5 m* @( A" b! e h3 {2 x. V* \
" @/ L$ {' B6 K" y' k$ N s = 100; // 现在编译时出错;需要显式转换:$ D# I% S6 a7 P- j- N, N0 n
" q# ]9 A% C, \2 K* M* b7 j s = String(100); // 好;显式转换0 O0 r9 ~5 V! m. A F3 j
s = "st"; // 好;此时允许隐式转换& L# Y. Z* }2 t% [ _: _* W
} |
zan
|