- 在线时间
- 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>
- w% @$ Q+ {/ C(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:9 U3 [, V/ i( ~: L: L
. |7 e7 U% Q' b3 _
class C {
& s: p! O* L( I: ], Hint i;& [0 i5 m/ r9 ?4 I$ y
//...
2 h" \. P1 a% p4 y. Upublic:( M( ]! Q- x3 B
C(int i);//constructor and implicit conversion operator
) z* p+ ^4 C6 y( I1 S1 m; y//as well+ ]" Y9 }) _' N+ X8 G( o
};% I+ N2 {- H" |) u& ^6 Q
3 x2 a1 b t3 ?' |& J1 gvoid f() {
3 n' O5 z- m7 I* Q8 ~/ w) r# R& v! K2 `
C c(0);
2 S/ s6 q9 o7 j0 v; f; C6 G: z0 V! f, P! \$ c, r7 ?8 Q
c = 5; //将 5 隐式转换为 C 对象,然后赋值! g. V4 R5 e# W% `+ C0 t
) F, }9 t! U. Z) {) c+ b}& L, m/ ?& K; s, D0 e
2 z' Q6 `: ?$ l- W) c
编译器重新编辑上述例子代码,如下:
& O4 j( M' J1 Z, O+ A# p' s
. Q8 q/ s1 i1 ^+ u' K J//////////////////////////////////////////////////////////////////////////////////////////
0 x% b/ {6 T- e1 C//"c=5;" 被编译器转换成下面这个样子:
~; b$ ~- C2 f* i: \, S/////////////////////////////////////////////////////////////////////////////////////////3 S) `! x( v& ]! j+ X- W$ w
& m/ f h" j' sC temp(5);// 实例化一个临时对象,
2 y3 J; {9 |" lc = temp; // 用 = 赋值+ A! z* @. o3 ?5 o; ^( s
temp.C::~C(); // temp 的析构函数被激活
+ ?1 w3 ?; {0 s& X) Z9 `7 P/ W0 B# ]3 R* ~1 m4 J/ X
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:3 s' b( U! v$ P2 t" K0 s; ]# b
8 J! U! |5 Y& W( V, Z: S7 ~class String {3 m- F; D: h4 g* ] X8 ~* ?0 B: g- c& G
int size;
$ i' |3 ^: ^5 ~- Kchar *p;
4 h2 f0 `# {' N- v. P M$ d//..! M& l; }5 r! ^! F3 I7 D$ O" v% ^
public:
+ k: R9 q& ~3 t1 X/ U String (int sz); //这里不希望进行隐式转换操作( M9 w& i& f3 `) w+ u
};, z/ T4 I h9 H5 o4 \' C9 h
void f ()
/ f( I! S' a( v* c1 A+ k5 S" W{
! ^/ x6 {- o0 d {% [7 i String s(10);
$ P$ ^4 Z" h. v: p' i( _+ d8 C% e# @1 b
// 下面是一个程序员的编码;发生一个意想不到的转换:
$ O9 [% ]" b% i* U! B6 w5 w( n, U/ f( M& t# o+ u. w0 m4 ~# P3 x. J
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
# u4 C3 M d( v* O5 a9 P}
3 b1 z1 `9 I& L) I# I+ I0 z
7 t: y3 l) C3 ]& m为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:. _; i1 c4 j! d) o, `4 z! e) m
/ r; R, k. V: a/ D7 bclass String {" s/ D y! M# b4 W
int size;& |5 p" l% r* Q: o7 {
char *p;$ l8 I% W5 ]1 ]+ n* X
//..
- U3 D; z- L" d5 Vpublic:
3 [+ N" J( n8 f4 ~% N // 不要隐式转换/ G5 o [1 v% Q7 L- H3 P
explicit String (int sz);
5 u+ v- n1 E9 ]6 q3 k5 i String (const char *s, int size n = 0); // 隐式转换
) e0 o$ V7 a! }};
% ?5 Q# {& x* C0 e& S0 ^0 u' O Z; u q- E
void f ()
% R4 E4 ?( r+ b7 I" L{$ b h6 U: m* g% `/ p8 U
String s(10);& [: c% S+ T9 M. M3 _9 K8 x ^
$ I$ S& I8 I" a6 o2 S9 J1 u; X( r
s = 100; // 现在编译时出错;需要显式转换:
6 s- P+ F2 o8 y0 C# w, `9 l+ c, k& B' O
s = String(100); // 好;显式转换
+ w' h7 p8 R6 f5 K s = "st"; // 好;此时允许隐式转换
( C: B. H8 S6 G7 `5 Y L} |
zan
|