- 在线时间
- 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>' |# |( T/ O, d
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
6 J% v! U9 u5 r' U( s) V
3 I' c; \2 U% @. A% _, cclass C {* h/ N2 I1 V; v
int i;
. {5 C$ b! N2 P; G1 G//...
. W9 ~# Z+ ^7 ~! mpublic:
0 X ?% c# d/ z4 i6 | C(int i);//constructor and implicit conversion operator3 T: }" l- c; a1 A- j
//as well2 p* k4 I4 b. C) X: F( q
};
* C. S0 P3 g0 f, |9 Z& p2 q, \" D: Y8 b
void f() {( @8 j5 O2 a/ A+ J$ y' K! X/ o
4 z; W r0 x0 K1 R% w/ L1 ~
C c(0);: ^! `$ s) e3 |8 W
; y* _- S1 N' w8 \
c = 5; //将 5 隐式转换为 C 对象,然后赋值
* M' q8 ?9 b# Y& ^* P. u) K; \ R" E& H- ]3 n3 s
}
) m0 d5 n$ m5 X" X" [; x& q' J1 u$ A3 G, K: X+ p
编译器重新编辑上述例子代码,如下: 3 p5 b- Z2 p( C2 k
/ R; g; C$ g; h8 h. M//////////////////////////////////////////////////////////////////////////////////////////- O) ^, J. y8 T4 b
//"c=5;" 被编译器转换成下面这个样子:9 G. H& q; `# k) C7 s+ N
/////////////////////////////////////////////////////////////////////////////////////////0 h1 z1 Q! S1 L1 ?
" B t$ ]6 E( o( O) S9 L: h* F
C temp(5);// 实例化一个临时对象,# {- k/ S( ]% \" S
c = temp; // 用 = 赋值
, h! K9 J7 ~- u, g1 D, v% Ztemp.C::~C(); // temp 的析构函数被激活' H+ T* o F1 f3 z( K! l0 U
0 T0 F4 E4 w/ x+ P" X" ]在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:1 j; i( |* ?1 b+ r. I/ N5 |: _
, l8 ^% B4 p. K4 n' lclass String {
! F! r. b) I+ y" kint size;
9 T9 f! p' _8 c) t) E2 V- ychar *p;
- \& c3 a/ J0 E//..$ g/ U4 C* f; ]$ k3 W4 e
public:
, A* S8 a# Z$ Z# O- r* g, f3 m String (int sz); //这里不希望进行隐式转换操作1 }/ f& G/ h6 t* T. o9 C" A
};
! X2 Q2 _ a; q* M! a! Y* H0 \; bvoid f ()
+ T' O8 s- I% N) v9 `4 e{
# }- d6 g8 o! D, j String s(10); Z5 N/ B* ^+ Z. Q( t' R' Z
/ Z) ^/ Q, L8 f g# R0 y // 下面是一个程序员的编码;发生一个意想不到的转换:
; y6 P, E' G* F5 G% }& w/ S$ F" F' W) g `$ y
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
: ?/ i0 R" D' b; u& i5 Q}
, {7 C4 q3 u* f! `# ^
' W& j8 y/ C' a' q: E" P4 d8 m为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:2 |+ v4 W! ]" u0 G6 K
6 s: q8 d% o" `3 ^7 ^class String {& S3 ~7 D' g# |: m0 F
int size;" Z# e) t; q/ f
char *p;
; f9 P7 I: X; K: p9 [3 v0 I4 m2 b//..8 C" o2 j( b0 D- e- i& x
public:4 _& k; d! Y! C. S3 T* e& b3 ^
// 不要隐式转换
: Z: d8 o& x/ `- ~ explicit String (int sz); 2 C9 u8 |9 z' K1 m: ]+ K1 }3 t
String (const char *s, int size n = 0); // 隐式转换0 j5 x: |3 ^2 \( h# W( S
};
1 T' _2 w. f( Y0 ?* Y9 p2 F& S% r
! X# t. G9 L) @( Hvoid f ()* v$ w$ h5 b1 V4 [
{ O2 x4 B# A e6 |) n9 }
String s(10);
3 a6 h8 ?' _( y' R
* T8 u0 X6 [' @, b& y7 ~" p s = 100; // 现在编译时出错;需要显式转换:7 u/ @& E) }3 U" e0 \: f- V# _
. g9 Y, y9 ^5 p3 k s = String(100); // 好;显式转换
6 G, u8 C3 i" n3 ~- \- ]* g0 E M s = "st"; // 好;此时允许隐式转换+ L8 Y# N. g; i$ ~+ M r4 x
} |
zan
|