- 在线时间
- 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 I4 G- d* x
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:! m- l" g/ ?0 Z/ S; F8 {
6 F& N0 c. I. Y; @/ gclass C {
7 ^1 Y4 n5 W' p. y: i2 }int i;
1 ]& v% q, F, N7 _" z//...9 K0 x/ U9 b/ q3 C- O1 F9 z k
public:
: d) {( J; ~# F' S1 h$ A! e8 d C(int i);//constructor and implicit conversion operator
) Q6 A4 z7 H- { q6 ^$ X" i: p//as well
+ p2 o0 t& e, a};
7 r- f5 f; l# ?3 ?; P
- t5 D! E4 D1 L, ~* rvoid f() {- z. T( ]6 o; L7 K m) L
; b) y+ S, V) ^/ [+ s1 k- m/ y
C c(0);" x) U& s' k8 T* ]; O8 c' [0 U/ @
5 o, r1 B9 ?$ C- {. m& Yc = 5; //将 5 隐式转换为 C 对象,然后赋值
5 H$ { J: E7 o: a+ O; J5 H- M8 T0 J! Q
}1 G# x0 S! l* A, m0 {8 {
0 A+ b2 P4 l6 q' x
编译器重新编辑上述例子代码,如下: q) A/ X) e9 o7 [# c
. ^* J+ W/ C% \* L- f/ j# w$ B2 M) z
//////////////////////////////////////////////////////////////////////////////////////////
2 ^& R' l! D3 E* A/ O//"c=5;" 被编译器转换成下面这个样子:
% p/ I; T/ n# j* m+ ? V3 d/////////////////////////////////////////////////////////////////////////////////////////
$ W$ _) T y# }) h/ \, a2 T; |' \2 a. ?7 @- i. p! s H
C temp(5);// 实例化一个临时对象,) Z/ T* r# k1 [* R; H4 E7 k6 u3 @
c = temp; // 用 = 赋值
% \& c2 w( d* f0 X5 S, R! Ztemp.C::~C(); // temp 的析构函数被激活: S& J# g, z6 B6 |. c# ~9 {
$ k9 v3 E6 q% C6 f. a9 P
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
* J6 n7 z3 ?1 O ?4 F0 {0 [! [
- a, B. U! ^9 `. Q# R& @class String {! w* H+ _- c0 u. y. p
int size;
. E: u% \8 q# m0 ` Echar *p; v ]" K' C; B$ a$ L9 t
//..
6 t" ^" t) m D. Y/ G& a. A8 xpublic:0 b5 V5 I$ }0 y
String (int sz); //这里不希望进行隐式转换操作
7 I5 K9 Q- O n6 h};/ Q6 n4 N0 R/ X9 z3 \
void f ()
; W( V1 p" n; ^, K, q: t2 e% p# k{; E5 V9 b( @; B2 ], W9 @
String s(10);5 T+ C- S8 d7 l" X* A. l
, C- p) ?7 j7 h // 下面是一个程序员的编码;发生一个意想不到的转换:
# v+ y% e; b9 }' ` k: ?! x" o% Q a7 Y
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s. a7 |% e V9 k. E- ~, t3 j8 Q
}
$ ^! U" u' m% S1 J$ {8 I7 z: b$ \" n: C/ j, Y) ^
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:5 c7 d7 ~: A. r) t3 V
- B* D/ E2 T* }* _( K
class String {
8 H) v. Q# E+ ^6 a" f5 Y Bint size;
8 k. Q/ t; p) z' w9 Kchar *p;$ u3 a( _. P4 p" H& V8 y" |
//..
N. j0 V& o6 v$ a4 Lpublic:
6 ?! j" u, x9 G% ]+ A // 不要隐式转换# v9 G3 d0 [- J2 U
explicit String (int sz); W! E3 H$ E5 X0 M
String (const char *s, int size n = 0); // 隐式转换# [6 t7 {& T$ c8 N! C) ^, d
};. b; j8 b; i* j# q' _
& Z# g& s! i* ^
void f ()
# N- D' t* \7 z6 v{
2 ^- H- t, o& U! p) h; b+ w String s(10);
8 J! ~, y& u% D
6 q4 i8 K' u" ]( L s = 100; // 现在编译时出错;需要显式转换:
$ ^% [/ A- b4 x$ R j9 H6 K: W* p
s = String(100); // 好;显式转换0 |' {/ \1 M& A/ C6 F: J6 p
s = "st"; // 好;此时允许隐式转换
1 L0 f4 W; Y+ h9 ?5 u X} |
zan
|