- 在线时间
- 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>- m1 G" x: o! m4 C' W
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
. Q7 H. q' G$ T: B% ?; o8 W9 \! H$ _" V8 t' o. w/ K" j
class C {3 L& }3 S: R' A9 H! i, d h
int i;
" R4 C2 A* h: E//...
2 z5 }5 }% u$ c2 j4 w9 ^public:
8 O- x2 U- h: \ B1 [ C(int i);//constructor and implicit conversion operator
: V2 ?! D( w$ C H, V& U//as well0 [9 d0 Q4 S) y% m& f# K
};
! q% E0 G7 g" h3 ?8 a0 W. w3 ~& W2 X, _
void f() {1 p& ]; X1 ?7 _
/ [4 l% q7 z' @& uC c(0);
, d& Q( r$ h. e
: J! L G* G3 ^6 ~' s* `" Nc = 5; //将 5 隐式转换为 C 对象,然后赋值
' k5 m6 ]" e! B, S: Q! x V( v( t! w, z, [) b
}
) m9 H( }% Q& q4 u0 W- G. [& q" x/ C
编译器重新编辑上述例子代码,如下:
/ Y: q: T5 B8 m2 [$ ^8 s
8 U: a+ f/ V1 H# T//////////////////////////////////////////////////////////////////////////////////////////1 {. A- C9 A; [2 F7 ^
//"c=5;" 被编译器转换成下面这个样子:0 Z ^0 [5 L- e7 O/ H$ F I7 l9 N
/////////////////////////////////////////////////////////////////////////////////////////
5 m) {9 F' T; M' W7 G. t, ^) G6 U6 ^2 h9 v7 v0 H4 z: O
C temp(5);// 实例化一个临时对象,1 r- a$ x' y' n# h$ t, W% v; N
c = temp; // 用 = 赋值
1 F7 r) B& P; B* W, P* C xtemp.C::~C(); // temp 的析构函数被激活 ^& A6 E4 y9 E+ Z# j" h
o) G* ^& V& Y1 }在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
8 g% V& h& N& B" S2 {: P/ H, \$ P/ F, {3 u
class String {! t4 d4 e) }1 ^! p8 S
int size;
9 ]( H% Z; j& {; v8 s6 ]. H$ k$ Mchar *p;
5 N7 z3 t9 ^/ G; P& G& w3 s//..( r- |' |( M2 @1 j
public:
0 {* W2 [# {3 o: B7 d String (int sz); //这里不希望进行隐式转换操作8 Q" Q( M$ `4 p! E4 X0 Y% Z) A X
};
2 w3 u# ?4 y, Y0 @void f ()( f. l# H, Q+ }& a; k
{% f- y4 ?) f9 I3 J3 S
String s(10);
' D1 r3 A5 ?: v5 N* J# M# S4 U) Z3 l0 m' X# u, c B" j" N4 y3 H
// 下面是一个程序员的编码;发生一个意想不到的转换:# M* F; m( J. w7 A7 ]
/ T) B- c' K4 H' P+ Y s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
' B0 [5 @: x- U+ J} ( ]( F& i" H4 m& Q9 G- }5 Y# h
$ z! j! o7 }6 I7 H$ j% w4 M, c# W8 z
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:$ _/ q/ ?0 _1 {9 z3 I
9 {* _1 C3 Q' d+ X& p$ q+ s3 K
class String {
2 S' b6 ~6 ]( |int size;
- N; w q# J% V* C% Lchar *p;9 F5 H$ v: S4 l. p1 O: ?( D: s1 S
//..6 q' `9 ^: R8 k1 j* y7 v
public:
$ J) u8 O7 f8 @# r4 m // 不要隐式转换
$ Z2 I% ?3 v2 G" ]& q explicit String (int sz); / i1 y/ A- E* j$ B4 q; S. v. N
String (const char *s, int size n = 0); // 隐式转换
+ v% ~, h( v" P1 H" T5 V};
" u( D! W: _9 p6 p9 r# r" w7 g1 B) M9 T: v4 H7 u$ o; F9 Z
void f ()4 O# V9 u5 _# j, u7 L p# V
{) ]1 n9 G# f" r2 N5 m4 @' K3 g( L
String s(10);
' I" R) f" G" w# O% ?: E/ t% V, z( G( |
s = 100; // 现在编译时出错;需要显式转换:/ x8 M! J2 t& x0 E3 Q
( C) Z: p8 |$ T" I/ X# `+ p; a s = String(100); // 好;显式转换& O; l: f f, q6 F) ^# c N
s = "st"; // 好;此时允许隐式转换# |7 s$ i( D( L1 U) N9 p
} |
zan
|