- 在线时间
- 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>/ [6 i' @1 o4 f
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
- t( D) K6 D, M* |: K, w5 p
8 ]2 G F s$ g7 ]/ I8 d; R5 uclass C {
! B4 q% R# E6 y( \8 n; Fint i;
`2 E( h; A5 v! s# H# ]2 ?" Y$ m, |//...' Y2 M( [4 V4 r5 i& E! z8 x
public:5 O8 q- t1 j5 g5 i! a# w
C(int i);//constructor and implicit conversion operator& `& ^" |* f3 ~
//as well) n$ _) N; `( h: N
};- c; t/ i3 a9 u2 D4 y" A
6 h) n; t0 _6 ?. i+ N7 e) R
void f() {! [/ D$ `) _7 l% U6 p
1 a1 } ?" S7 u$ wC c(0);
5 l5 b# u! N% O1 W- ^2 ^
) |2 a" n$ e( y, q" Yc = 5; //将 5 隐式转换为 C 对象,然后赋值% [9 j# [0 j# i; o, k
- x8 A' t# l( ^$ n% i6 j
}
" m3 K' Y/ x) D: ^& U5 ~, @9 n0 u4 w! ~/ A$ h" \
编译器重新编辑上述例子代码,如下: ) C- q1 _8 q3 m& k
" Y; l$ ]5 U8 U8 \. L3 E5 R! \//////////////////////////////////////////////////////////////////////////////////////////
" K& k: z, }, P) U, d//"c=5;" 被编译器转换成下面这个样子:
) ]/ t+ q7 M4 V4 _6 B. Q1 y& K. ~/////////////////////////////////////////////////////////////////////////////////////////
6 p9 G- @. o- E* w! x' |2 m! d: A# D+ L3 _2 p! l
C temp(5);// 实例化一个临时对象,+ t3 ]. ^ Z; g+ @
c = temp; // 用 = 赋值
" ]1 |4 O. r( r$ L- A; Vtemp.C::~C(); // temp 的析构函数被激活
\/ o2 c# N/ g& p3 g% k3 T6 D1 U. j+ \, D- b6 r
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
( A% _5 s; J3 t% |( o9 J/ q3 H+ M* F, R/ }, Q
class String {: ~: ]! l7 `2 O" F1 H% f( ^
int size;% T$ w3 H- z% K" |
char *p;9 [( g8 }4 ^ ~) d' e/ X# K
//..
# C8 V4 K, v. t! Epublic:+ v7 h# k- u9 o' j! _7 @ a; C
String (int sz); //这里不希望进行隐式转换操作
/ y$ M+ `+ x2 Q6 ]( C" i};
: |7 k8 \$ E( V) \$ H; [# U8 ?; d" xvoid f ()
7 h i. [9 O5 p{5 E- e9 y, c7 e/ y# c% p1 T7 G: R
String s(10);
/ a; p4 \+ j5 i6 G9 L+ z
E0 m/ b! O& K5 M3 J1 u // 下面是一个程序员的编码;发生一个意想不到的转换:
! n, F+ O# E" n9 a5 f4 `; b
8 {, H% X& u1 _8 Y5 b; S; c/ _; B- ^; n s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
9 j+ x" [8 L. ~3 X( D( H} " F1 Y" ?8 t: ?) W1 a
, g! S& P' n6 z T. r
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
9 m6 `7 S% R) E; z, s: R( \ x8 \* }
class String {
. [7 j. S5 n7 `( Y) tint size;
+ A9 ` {: e, r6 ichar *p;
* d5 \! p i4 B7 G: K//..
" _2 l$ w8 C! E) H3 J3 o! w. q: ^* Epublic:
( F$ k- O" L& q; e: ~' b. c5 ] // 不要隐式转换; g' j' f5 F: w8 M
explicit String (int sz);
6 M* x7 E% Y8 I0 a String (const char *s, int size n = 0); // 隐式转换
9 j; S7 y% \& n( Z};
7 O3 g. p* V f1 J7 ^( b
a9 u& O# w0 r Rvoid f ()
! N! H1 g5 |9 @7 d. d{
' e& G! L, c" C: C" z- y$ i, ?4 W String s(10);
. W7 S4 P9 A# l# b4 b% z/ j3 J H' I
s = 100; // 现在编译时出错;需要显式转换:
( F- ~+ u/ t7 J0 D$ E7 a" Z i& E' w7 |6 p6 s
s = String(100); // 好;显式转换
# X& @5 }# e5 k! [$ M% v' { s = "st"; // 好;此时允许隐式转换) u6 [, r( l7 V4 z; J: y( i
} |
zan
|