- 在线时间
- 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>0 d* N% V" c$ u% @
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:* n5 o% Z; T) {! K7 _/ Q( x
- k% @# p4 `/ D- X, t3 [
class C {0 J+ a- V: v! p" H" `* t
int i;! i7 y' u6 d3 |3 I. s, K; ~* E
//...4 f, o% m2 k- ]( W! C" A
public:
5 [5 Y5 `: X$ p5 F C(int i);//constructor and implicit conversion operator& p- l8 x# |8 V
//as well
8 N2 q b% P3 Z Z$ B: {};
/ ?5 v; k1 a( N6 o, j ^5 @( M( @* M) O R2 _/ b' c
void f() {8 O% |9 X* h& Y# w0 a% I8 l5 ^1 Y: _
* }$ P* M* G# h" {) FC c(0);5 {: R2 |% R# W! }- @7 x8 s5 B
2 k$ B0 }, y; ?% i8 Q: H) E
c = 5; //将 5 隐式转换为 C 对象,然后赋值* z0 I/ f$ Z( j' v/ B
. a- y* Y' u$ C
}
* r) r4 T3 A8 B) d1 Y8 D+ u8 B+ J7 ]9 E% x- p9 W) X
编译器重新编辑上述例子代码,如下: 8 U8 d, L, d+ @7 k/ n9 h3 y
- q6 {, q3 W' F) j. i
//////////////////////////////////////////////////////////////////////////////////////////
7 W; P1 B: b* [//"c=5;" 被编译器转换成下面这个样子:
) I% b/ z/ ?7 Y+ _* s/////////////////////////////////////////////////////////////////////////////////////////# o# E* ?8 h3 a5 d
: z$ Y8 [9 _7 F& eC temp(5);// 实例化一个临时对象,
$ S2 P$ C# T/ ]$ uc = temp; // 用 = 赋值8 k1 W! |+ j, L3 c+ u$ g
temp.C::~C(); // temp 的析构函数被激活
2 b2 _ g; ?. \- u
v5 u2 e& E, Y c; a% q0 O在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
$ f- i. ~! b+ B! H# r. v
$ g% \- a! s3 Z u! p* c3 Yclass String {- ?; D8 C! D2 X; |) Z/ y. ~
int size;
; u5 t( q& c2 {2 h0 Wchar *p;
' S, f" W* }: R; D0 c# N//..& ]# B9 @6 H1 ?$ @ {0 X. [/ W! v
public:
4 N; q. w. V$ A String (int sz); //这里不希望进行隐式转换操作
% T) r* f7 ]$ Q};
( d8 B$ D, t$ H. G9 S! Wvoid f ()! C$ l7 @& T1 v [: t+ S5 V
{
7 v E/ }' ^; F: h1 C: L String s(10);- T4 {4 X6 X. Z" O
# p( }2 _ g! u/ a7 e
// 下面是一个程序员的编码;发生一个意想不到的转换:
5 F3 e9 ?& {& ]! m. L% C
# \& U# z# P$ ?" h s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s2 M; o( f! f* ~& n, y3 Z; o$ X
} 2 F" U) s2 J( Q& L. S
. O% `& G9 B. s4 E% o' K: {- o为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
# X9 c8 X5 c3 n: R0 K M. R. y( j2 h* S1 P& ?8 B
class String {
2 i& x. h' a6 V4 s8 t5 ~; B8 p, lint size;; ^ g0 x& a4 c1 M! A6 v4 L2 X
char *p;
. U' c# Z" @6 U, e4 i) }9 U//..
& A \* c' j2 d+ W, y# Opublic:4 j& x! V1 I: y( F% B) d
// 不要隐式转换/ a+ p3 j( S6 i# E
explicit String (int sz);
+ z; I+ M' }- c1 M3 D String (const char *s, int size n = 0); // 隐式转换
3 R) f) \7 s6 {};" B; |5 b& y3 I) N2 R
1 Y1 r0 w3 w" h
void f ()4 s7 _) {! g: d* T( D- p' n4 b
{
, T+ s" p6 s7 H9 p# g# Q5 ~' R String s(10);
; }7 L+ @3 D* G- z% i/ F5 I6 ^; @2 ?( g+ f/ C i/ F6 p
s = 100; // 现在编译时出错;需要显式转换:4 }! L- q: E4 x3 {! L
1 W) N6 k7 z. q# ~5 A& m9 Q
s = String(100); // 好;显式转换
! ]/ k6 S6 m- a3 }# q6 o s = "st"; // 好;此时允许隐式转换. O+ R w* R1 [9 Y0 \6 @
} |
zan
|