- 在线时间
- 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 f3 w3 C0 O' a% n$ P+ O1 k/ a(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:7 u7 L) V- w( n( T n( T+ o$ w. ^5 I
" N6 y* w( x* |3 P2 u
class C {
; y6 n7 r; m) Sint i;( A) A( _4 y/ ]! d6 `( h5 g
//...' B* P( I; n' p; m. z; S. }" I: M/ Q
public:
) q. H& b! h7 t& v- }% ? C(int i);//constructor and implicit conversion operator
- \& h# a3 x, h; _3 r4 a//as well
1 e6 M- m6 c, L0 h! T6 B9 b};; v+ @$ H- V! o8 I6 l
% h0 X* f! ]# u" y4 J z
void f() {$ Q5 R0 X0 c7 \- m$ L# t, W% ?4 F& J
2 g7 p# I- L- F& B- hC c(0);/ H9 m9 n! P! w- b5 k
- Z( w% g2 o- \4 z( w$ x1 Z
c = 5; //将 5 隐式转换为 C 对象,然后赋值( O- x& h8 U6 U$ Q0 v
& a- R$ I# ~* g m}
1 J8 @% v+ o( c( L" Q0 D+ s4 h/ t
编译器重新编辑上述例子代码,如下:
+ ?" I: q& ] Q Y+ d2 E( s, a8 F" s
//////////////////////////////////////////////////////////////////////////////////////////& h6 F9 [6 N: {2 r: s
//"c=5;" 被编译器转换成下面这个样子:
% p1 s" b5 z! b% j8 f a/////////////////////////////////////////////////////////////////////////////////////////: c, P. ?7 |4 d+ D5 ?
+ T# Q* s6 K: q1 j2 `" {7 f
C temp(5);// 实例化一个临时对象,5 O! T, e4 f4 q, z
c = temp; // 用 = 赋值
( O/ N% I; W/ j3 c6 \- G5 @7 z1 I2 Gtemp.C::~C(); // temp 的析构函数被激活! C, B# F, t% h8 Y- N
/ a, ~2 V8 _5 b. K3 Z( c
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:- ]1 F( [2 H2 O& U) J6 ?' n" k" n: T
! w* f/ w4 y, s9 q* ~( T
class String {0 V: U) b4 s4 `( B# f2 t
int size;4 t6 q/ ~2 \- B" ?6 c u' H
char *p;9 O: z: _3 Z$ x& o; {$ X( s
//..
1 m, Y( S' ]7 _! {* s3 cpublic:
3 `6 s- C! x0 _3 g String (int sz); //这里不希望进行隐式转换操作 ^( p# C1 m! K4 y5 \% z
};' v9 M! ?! L( I# G* T* |
void f ()
$ e8 E. |- _, p6 F8 M{$ ~0 U% v3 L% Z8 R6 W# M! C
String s(10);
2 S. Q9 q, _+ k# }
; x) @# K' n: }) b& B, G3 ` // 下面是一个程序员的编码;发生一个意想不到的转换:
1 m( x: D" D' f% P; N$ p
5 H# Q ^( n8 a s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
; X5 p/ U. B9 P, g' r/ _1 ]! K. r}
1 ^3 }1 J9 B* D; n4 K; z
% a8 J4 s3 @# s8 x$ R0 \为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
1 R0 @9 S8 |0 {* |3 X; l/ E6 I2 G3 \, F0 m: F" H/ k) A
class String {
- t: ]" ?3 D0 o7 w& Tint size;
: v4 {" m, d. a5 B3 y% Bchar *p;
5 `5 Z- t% U+ ^" p//..
( j8 |- {4 J& D; ^8 Fpublic:, L' a6 o$ K+ v/ T# Q
// 不要隐式转换& t" X& | r% q. C9 E- S) f. K
explicit String (int sz);
) v- L& T2 y7 q( z: l String (const char *s, int size n = 0); // 隐式转换, Y7 t3 `1 a4 w" X3 @$ O, Q1 f
};, w+ x. {& y$ m: _; K
$ \$ n8 L% n8 [+ Y2 k Bvoid f ()! I. X" t, G* ~$ F" f* z
{
( u5 k/ q" L4 o o String s(10);) |+ P0 `. Q: M7 U# D7 H2 d: K
0 Y7 [1 y( S* c, Q$ m8 \. s O
s = 100; // 现在编译时出错;需要显式转换:
: }. `) N& O* |0 w* Z6 c. N" Y; h- |6 n( T! W2 T
s = String(100); // 好;显式转换& S: X9 L" f" n0 e, u' u# {/ r) I
s = "st"; // 好;此时允许隐式转换1 j) y8 z8 p$ S: [9 u
} |
zan
|