- 在线时间
- 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>: N: u- b, @) ?' B1 y4 G# Z
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
" q8 a/ i! Y$ O, u2 D5 B3 _& y6 g2 b1 t. ~4 W+ i
class C {
0 {' v. @1 \3 {; P6 Z$ ~; lint i;8 ^! F8 X: b7 l
//...
" s; V" { A9 b' p- `& s! y) tpublic:
+ f0 A/ z7 Y0 u @* ? C(int i);//constructor and implicit conversion operator
# F7 o" J8 g, q* I- j//as well2 D, C5 }+ U0 L/ k/ t
};
* ^5 k1 c2 p$ [( k* ^. {" X2 K5 C7 [: v) u1 q3 p3 c* F
void f() {5 P/ I% C1 m3 U9 k" }/ w
% j' I9 j2 v! r5 |C c(0);
# I" F1 o4 O" k c6 N, m
) F* I G# v# r6 z4 hc = 5; //将 5 隐式转换为 C 对象,然后赋值9 G) p/ m2 ?+ e+ f: D# h
' M, h3 e2 D/ \' H5 y% z' l
}
. r/ N7 c1 N, x1 @' ?8 Y
7 w) _. ^; s- J+ ~' R5 C' g# X编译器重新编辑上述例子代码,如下:
5 i7 p2 H' c. T
% ?. M& E# b- A2 R$ r4 I$ ~8 Q7 m& C7 t! V/////////////////////////////////////////////////////////////////////////////////////////// j* b( R2 q, ?4 u" |8 \/ t
//"c=5;" 被编译器转换成下面这个样子:( ]( \) E5 [! J# H! G7 f ?
/////////////////////////////////////////////////////////////////////////////////////////
* y- [( V1 M1 O, i8 s( V4 r) a4 ], y' b( o+ B) h$ E) M0 @) b: A
C temp(5);// 实例化一个临时对象,
+ B! s- I% `, F: H4 i% Mc = temp; // 用 = 赋值: e; X# G5 R3 Q
temp.C::~C(); // temp 的析构函数被激活
8 M" ?8 B5 ]6 i* x+ H' I5 K3 a7 t$ O2 V$ j
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
1 \! l8 J$ G8 e- ?" G& L0 q: D5 y; @# B/ f
class String {+ m) W4 d, m) E4 w
int size;
/ p, r7 J, B9 X4 g8 B7 tchar *p;
! ^1 c3 c) X5 o$ `' D//.. D9 V8 ?5 x8 c, @% \" H- L/ E
public:; D+ f% i1 F0 R6 K) i
String (int sz); //这里不希望进行隐式转换操作4 t( c" |1 y9 F* Z! w) a
};' K$ _ }) [5 d9 z5 X8 c: M+ w
void f ()
* O! }4 t1 \/ K& N9 q{
( p( w m2 \' G* w. [/ I+ L4 W) {0 J String s(10);
9 p; ?, W7 Z; \& h) Y5 V
3 m7 v" \2 B2 J: h! a3 g1 o // 下面是一个程序员的编码;发生一个意想不到的转换:9 U5 T3 O5 B& T6 }: _( w% l
: R [- U3 M5 ~$ e9 p5 d
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s& E& {6 G. o0 G, r
}
7 w6 Q4 R2 l2 H0 w8 k
0 H. j/ n$ X, q# k为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
7 {/ m2 t! ]& [" ?" V7 d$ D& k* o0 ^% U' q) l9 y
class String {$ ~+ h/ m1 I' q2 @0 n8 L6 j
int size;
% |- j- f- I& M2 T- S& ^char *p;
$ w) p$ u6 a: n' q- G% `2 l//..
2 k" H0 o! z( E: L+ r) L& A' dpublic:
) T Q& |9 X! K6 x% N- ~4 n // 不要隐式转换' j9 J" S! o2 W& G. V, t+ o4 v
explicit String (int sz); 9 B- g7 j6 H- V
String (const char *s, int size n = 0); // 隐式转换* T% s6 s" h" P- d& U
};
8 W4 D$ J" R W6 L* G6 R! v/ W5 r* |- o# z2 o2 P% d3 r
void f ()
! Q8 A- q3 `! F$ v, v{
6 H; f, t+ Y0 u String s(10);7 p- J8 w& w* c
& p% E8 }5 W/ h# w/ Y5 Y s = 100; // 现在编译时出错;需要显式转换:8 k9 n# d6 Y7 n
. t* n% N5 Q M- M
s = String(100); // 好;显式转换* e8 z( W: m9 u8 h; [
s = "st"; // 好;此时允许隐式转换
4 D6 O6 C& p8 v/ {+ x} |
zan
|