- 在线时间
- 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>
1 K' ^2 \# d2 U+ I(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:7 H. n- J/ \. q5 w% J# K8 B
7 p* j! o) ?3 J% N9 i5 o2 l
class C {
/ X" @7 G3 e% s: M+ G1 Eint i;# ^; [; P, X! H: H3 I d
//...4 u C: z$ u3 J+ p9 I2 R5 P! L
public:$ h7 s/ \1 K+ k! v
C(int i);//constructor and implicit conversion operator+ M; R3 \9 ?0 l1 ]. R3 Q5 I
//as well
* ?( P0 n5 w2 y# L( d" R% ~};
/ ]/ w* `* P f
1 s, \2 j [- u+ gvoid f() {" o: G/ ~; I' K6 g: W7 E' Z
* h, r5 z4 ~2 O& P1 YC c(0);
3 ?, a' }5 x" v8 S. g) r8 `+ a0 y: _5 q: A% i1 R. }+ Q
c = 5; //将 5 隐式转换为 C 对象,然后赋值! m- T4 c9 N$ @9 Z$ I+ I# }
% P) V& u- }+ D" S# o. S
}
9 U* }- c2 _6 D" p- W5 y8 m5 N: f& S5 j I
编译器重新编辑上述例子代码,如下: ' @5 Q. y3 O" h
2 _3 E$ I& F" M8 }
//////////////////////////////////////////////////////////////////////////////////////////
( \7 b9 f F6 _: a( b//"c=5;" 被编译器转换成下面这个样子:5 L; F1 W- U$ b
////////////////////////////////////////////////////////////////////////////////////////// w6 I+ S! Q& Y2 J: ~8 D$ N
5 m! }0 h# E7 L6 aC temp(5);// 实例化一个临时对象,
3 q* r- n/ [3 S8 g# ~* d/ b6 Hc = temp; // 用 = 赋值5 i* @$ P; l" `3 p8 m
temp.C::~C(); // temp 的析构函数被激活1 S% ]) X4 F0 d
$ r% \ ~0 x5 i1 g$ I
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:5 H2 y! G, N" F2 W* k. Y
7 r8 r2 ~9 J: M: m, n% `
class String {4 H% v8 w3 a7 u5 j4 t4 p! u& \
int size;
/ B/ G; @) Q- D; X- Dchar *p;
$ A$ x% @7 ~7 {$ J//..
: R% ^3 a+ g: b; ]3 M' F+ s# X; Bpublic:
' b9 U6 {# ?# g9 S String (int sz); //这里不希望进行隐式转换操作
+ ?5 S3 l: Y9 {};4 x# [" c( H( [7 v/ R- z6 u" a4 r6 p% z
void f ()" A0 C+ c+ i+ k0 Z, ~
{& h1 S* F8 T8 x1 G) K8 P% q) `
String s(10);/ R8 P9 W6 f& _( D
( \, {3 s! o' h- d4 q
// 下面是一个程序员的编码;发生一个意想不到的转换:. p# U) P, T ]5 R5 p- B
" B6 f: Q$ m0 g- t s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
& ]/ |6 n# W" j4 S( E} 6 R l. _) J6 _6 B# n8 o! c1 B. Y% l
* u; F3 ~8 r0 a* j
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
* z5 M0 C# r& _3 f4 O1 g2 x L& P6 D. j3 |0 ~$ m5 V
class String {# w6 {; {6 i" X
int size;3 V+ S! ?) T. ?; j- c
char *p;$ q- K( c/ Q! r
//..
3 v! [' _/ R; o6 [0 opublic:
+ v! ^; `% i! p- k' s. V+ q2 ~ // 不要隐式转换 {0 j; Z1 C. f; e6 _( I P
explicit String (int sz);
% t/ L' K1 l5 j8 _6 j2 o String (const char *s, int size n = 0); // 隐式转换% ?/ @) n" f7 j/ | x
};5 R# r: ?) {& G8 Y7 o5 }
! `) h% H+ R: n( j2 F
void f ()" M5 K9 H6 E- g* k( E
{
* ^% `# s/ P7 x$ R' b' d String s(10);" R1 U% @0 U6 {. [8 v% V
+ Q6 Y# c0 M2 U* t a s = 100; // 现在编译时出错;需要显式转换:
. A- }4 s1 x3 L9 w1 u: x) K- Q5 e F( J }* Q5 `( |# z* N, G
s = String(100); // 好;显式转换7 s' |% J1 Z3 a+ S7 D! O
s = "st"; // 好;此时允许隐式转换
# Q. B9 d. K- V" {} |
zan
|