< align=center><FONT color=#0033ff><B>认识 C++ 中的 explicit 关键字</B></FONT>1 ]( O- ~* w* R+ l
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:8 L* q K. i5 s+ o3 `# ?
% W5 J/ S5 U+ Q4 p2 g6 vclass C { }% ~+ n7 {5 ~' D- g
int i;- a" R# {) q) j& ]/ _' R5 w
//...# E0 ~4 [$ P6 }4 f) X9 {7 l
public:) x2 ]& O- s Z9 `* e
C(int i);//constructor and implicit conversion operator 0 y$ q. o$ I% e" M0 b9 Y1 n- ~0 F//as well; n' b. Q6 c! _* K0 f$ _# [
};8 z, b, T$ R! L8 s- U' x. o
4 P, J5 i L% G$ q
void f() {9 M" ^/ ?4 |* j, ]" k
7 E1 ?5 h' P! a: e0 fC c(0);3 Y- @; |" z/ e7 S2 T
) B0 r) Z: q2 O" v: p2 q1 \) A, c+ I
c = 5; //将 5 隐式转换为 C 对象,然后赋值 K, U8 N @/ [4 P
8 N' L! G' n9 C p} ! [: F8 o; s, U% S; t) ^5 a : z. ?$ r, ?% f+ s+ a& \编译器重新编辑上述例子代码,如下: $ \% T: L' [; n+ |, t
! c% k. |9 w; G. d W//////////////////////////////////////////////////////////////////////////////////////////; B. x: Q/ V5 `; B
//"c=5;" 被编译器转换成下面这个样子:1 x. f# {0 d. N2 E0 x
/////////////////////////////////////////////////////////////////////////////////////////) C# u5 d/ n, X& A* f* b4 ]
. ` P' b/ C9 a! M6 KC temp(5);// 实例化一个临时对象, $ }" K4 \5 f5 H* T( j. O. ~c = temp; // 用 = 赋值 ' h+ e9 v9 L6 Ztemp.C::~C(); // temp 的析构函数被激活 6 P" ]' E9 n2 R( O& i- q! l ; ?6 _ b1 M |, P S在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:# Y+ P8 w2 c) @6 Z. }
: C. w' w4 `: S9 ?6 T
class String { 3 S* H* q, k4 K1 bint size;* a; S8 s: K+ a8 C1 J' Q, r
char *p;& \1 q) J7 k: b2 K0 v
//../ w. b; p$ M% l
public: ! v3 X! [7 L7 h9 }, m L4 J8 f5 O String (int sz); //这里不希望进行隐式转换操作7 l4 U3 s8 }# W5 K; @2 l3 w
};, d% v2 U! R: h8 z8 D4 r
void f () B5 [* [" m% o% Y% \/ X2 r
{ 6 a6 D/ K3 d- D! N String s(10);) D3 r% |! D; d* X0 I2 Y! H
2 e- C% q" X, [: n/ y
// 下面是一个程序员的编码;发生一个意想不到的转换: & _7 p( ?0 B7 X: d' E( j9 M8 X$ A" I! S9 ^
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s 6 `' e: h- X( W# Y, q3 G} 8 g5 S: j) _+ R" w+ c( P# C; p/ v6 b; _* y, F( Z
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数: ! t- S7 ]9 r" {9 H- l- F3 l 6 f3 X" u6 ~' j1 W7 aclass String {) }: x8 I g; ]- T6 U
int size;; w- s3 p' i. N: R2 o6 q+ z
char *p;1 Z( Y2 J8 L V- G T! ?
//.. - P9 n* Y# u8 M- e, Opublic: % J* N7 A" l; ~2 t9 i: H6 H$ ? // 不要隐式转换7 w3 W7 X h. @( y4 s K- a
explicit String (int sz); 5 Z( _( G' B& X9 m2 u5 p String (const char *s, int size n = 0); // 隐式转换 ! m2 u Y2 d1 Q! e};0 p0 ]: i$ s5 Z) U* j/ b" c$ A
5 ?8 e& t( z% I: ^8 d' g5 jvoid f ()+ J1 Q" m6 h- {2 s
{ % {% G+ I) Z/ Z0 l% N* V3 V) X( t String s(10); * H. ~2 Y$ w5 W7 }; z7 Y3 L 8 W3 s) E9 g2 Y7 X0 L s = 100; // 现在编译时出错;需要显式转换: ! m8 h/ \9 N+ u7 B, `$ z% n, G. g! m5 a Q2 |' P1 u
s = String(100); // 好;显式转换" a$ H. C# [2 G. n/ i o
s = "st"; // 好;此时允许隐式转换 t: y$ W9 i1 r' l' {0 y}