- 在线时间
- 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>, Q& r7 d# H" @. A. I( p! E& ^
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:$ U5 y; S. A& E8 v8 E' w# ~) `
2 B- h |7 w9 ^
class C {
5 t$ X' R9 z4 o1 C1 q: u4 `5 ~+ nint i;1 e m- @" M* H: {
//...
: D2 o5 |7 C# M5 B% A$ Apublic:- E/ X4 Z3 y6 m. Z, J
C(int i);//constructor and implicit conversion operator
' y# ]0 L2 H% }/ G4 g9 d1 O//as well
7 V( G- B$ Z1 m. `1 A; i};
- N+ s+ Y: l: @7 o& `7 H' r5 e! |( @
void f() {
2 `: S4 O/ {. W# S) ?6 E1 F' s% n- F5 @1 w# @
C c(0);
3 K4 h; g6 q: U" s' [+ N* [3 r* d4 r6 z6 S! o
c = 5; //将 5 隐式转换为 C 对象,然后赋值
' n" s- v. d( r( v/ ~& ^
$ K& T% W& X2 a/ P+ ^3 l& X}
0 u9 d! ^1 y) ^' S; a; h* ]5 a- E7 f' i
编译器重新编辑上述例子代码,如下: : V5 b) N( U4 T6 Q' X( j
/ K- `5 K# z% `; E, ]//////////////////////////////////////////////////////////////////////////////////////////& K! C* n- q( Q v
//"c=5;" 被编译器转换成下面这个样子:
+ D' v, S5 a# n0 D/ [% l/////////////////////////////////////////////////////////////////////////////////////////
9 J% d5 }9 g/ D' D' ^4 T
1 d6 x* n. M- z' Q1 A2 o* V, d3 gC temp(5);// 实例化一个临时对象,
( h/ m3 h5 ~; c; L3 q9 Oc = temp; // 用 = 赋值
% |: Q0 Y6 t/ S, r9 o8 {0 Z5 ftemp.C::~C(); // temp 的析构函数被激活5 p E( {% O% H8 e' z
3 I7 k( F6 w- v$ G+ C) u7 F
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:) \& t x! h5 w% }' l
, q$ D5 W+ ~2 Pclass String {
* G- B* }- h; ^9 j, `2 O! V! R- k, Dint size;
8 l E& E7 f9 L$ Q `char *p;
; `. C+ {6 t3 P- H0 b0 Y7 {/ e. _//..
$ p! j6 ~3 F- zpublic:' E# J4 b% D* C7 U
String (int sz); //这里不希望进行隐式转换操作
# D6 A$ J# W* F};5 E( P8 x8 S3 }, `* y. [
void f ()
( @) o. ]4 @. p" Y$ c, l5 L5 R$ R9 e{
3 Y O! O8 x E2 {& n0 A String s(10);
* g h. Q! ^7 ~; A- S" N
+ M" m1 J# ~! t. _: z# Y3 C // 下面是一个程序员的编码;发生一个意想不到的转换:
" n% ]3 S8 d% \! M$ A/ n+ X& ?' |& @' \+ }) i1 f
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
7 ~7 |3 W, l5 K$ Y}
; Z1 b+ @* Y/ k& r" D- Z: m' O4 i, K; W. `3 i6 l
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
/ C- v/ r5 q" Q* s$ e
/ G5 x7 R2 {4 W# @( u- Cclass String {/ o- k- R( o1 `- F- P/ r) p) l/ d
int size;
2 c1 J2 s, X: Y. ]" z, Wchar *p;
! H6 O- `% C4 @" d$ n7 b/ W, Y9 M//..
$ k( B+ B, b: s. p) Qpublic:
- t3 @4 {, ^+ e& j0 p: l // 不要隐式转换
6 w- R9 s7 h+ f3 t4 @; d3 G explicit String (int sz);
3 Z& J- M( u+ W9 j# E: C D( {; Q6 X% p String (const char *s, int size n = 0); // 隐式转换' f. D5 m+ S7 Z) ^
};
! @! q* N+ _- b. j" J6 C! `! q% P! X5 \! l+ A* C) e' ?
void f ()! b. Z$ J% B0 [$ d* N# N: L% V
{, f) V, p& z7 E4 I' b% F3 v
String s(10);: v0 y1 ~* r* h' W6 m8 ^
5 h7 \& H1 f0 L
s = 100; // 现在编译时出错;需要显式转换:% G! F; l/ H) E: b6 @. K# k
. r+ V) w; U2 ]. H9 } s = String(100); // 好;显式转换# ]! B9 N- z0 b$ b* Q) t7 w9 P
s = "st"; // 好;此时允许隐式转换* X* g+ U B1 V+ m4 V# e3 n
} |
zan
|