- 在线时间
- 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>( \& u5 `0 g2 _8 ]( j4 K* v
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
4 E; h7 }0 \) `5 H/ o# X7 C) ^+ L3 N i0 Z# J/ z) d+ O! _$ ?0 K# F
class C {
. M2 ^5 H6 _% I* C% b6 rint i;
" X0 I% G$ ]0 z5 H//...8 n( b# @* ~: H3 \
public:6 o- A; e0 H8 n" |; ?4 o8 D
C(int i);//constructor and implicit conversion operator0 @; W0 H0 R) W0 @' y0 ]
//as well* d0 D/ ^( v% ]2 W
};
" v6 U" r7 p9 C2 P2 i# E$ A* e& a) N$ n6 F* m# L! a
void f() {
' t0 \% S7 D! f6 Z# D5 b2 K
3 D/ H- e) Q$ Z# s/ @# {/ H3 kC c(0);! j2 d1 i/ d! z
9 t1 P7 ^, ]* S$ X8 K5 {
c = 5; //将 5 隐式转换为 C 对象,然后赋值8 ?1 f- p7 F3 R9 u$ w4 N- W' ^6 H
. G; p( w5 E$ `& T% k% P# s3 w! M7 a}
* z% D0 B. [) C: | G. o
' S4 K; M- m: c" }4 l7 I$ ~编译器重新编辑上述例子代码,如下:
9 D0 K' e4 x- b$ G: v1 U q% n" m/ U$ }5 g4 q3 a7 R
//////////////////////////////////////////////////////////////////////////////////////////
0 q+ p: {: {9 r" o" P: l/ y, t//"c=5;" 被编译器转换成下面这个样子:- d2 i+ q9 {, e. E) B
/////////////////////////////////////////////////////////////////////////////////////////
! b+ ?6 W3 S2 ~- T! S1 b: i) G9 s3 o! S6 |# v! m% B+ ?
C temp(5);// 实例化一个临时对象,4 n3 s; y' P% x' p6 X
c = temp; // 用 = 赋值
/ j5 R6 Z; y4 i+ ]5 Wtemp.C::~C(); // temp 的析构函数被激活
; |6 O- o/ N2 m9 o# Y4 |+ A8 H" }. p# a4 k2 Y6 ]" \
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:0 X$ s6 w9 [' s- t5 y
8 y( [' m1 D6 v% E/ Z/ \class String {
8 B& O) t# r5 x$ kint size;* G% i" v$ u. ]" U0 O& K
char *p;- h0 w8 M9 B, f* B4 h* S
//..
% m$ q! Z6 k+ wpublic:
" m: z) ^+ r+ C7 X. a, Y String (int sz); //这里不希望进行隐式转换操作
% |, @4 i3 ^( f6 {) l9 w( Z4 R};
9 q3 F9 {/ f0 n, jvoid f ()6 _8 U" j* _; \2 B* g& P G
{
3 W7 O9 B2 H6 c2 Z. a% p String s(10);
8 y& R" v8 A) _4 ~, r$ w9 b) f+ b9 G7 C
// 下面是一个程序员的编码;发生一个意想不到的转换:
9 o7 b* z. S$ ?+ S, J9 ]
# }4 W( d7 @4 b( o$ l4 }1 | s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
) O6 o0 @$ V2 u, Z} + a) b& _+ l9 m" }2 }6 Y
' I+ x6 U# L+ Q8 W; A为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
7 O) E& @) F* v8 K3 y: m3 v1 ~+ U: S. Z c z: C3 F) O
class String {
* Y: A; g( k4 l+ J! p7 lint size;
3 i" ?- V: K0 rchar *p;- V) s# A! v/ x" m. H2 e
//..
( ~$ O5 I# @6 G/ l a! T5 kpublic:
4 [# G y; U; J$ x // 不要隐式转换7 y) L4 R5 ~9 J: U9 a
explicit String (int sz); 7 I, r, n. ~1 U
String (const char *s, int size n = 0); // 隐式转换
7 u! l4 J( D) p6 X7 j k0 Y. ^};
5 W* k$ k8 q( e4 i3 x7 z+ \/ l7 K. R& ~
void f ()1 `* \3 D7 F: E
{
+ ~! h/ a5 Z9 `9 F. P* Z String s(10);
4 s* I, s* f9 x. [4 D7 |! d b& l3 L& J/ `' p; g! @3 G9 Q% n
s = 100; // 现在编译时出错;需要显式转换:; t5 K, t: S/ ?
) f, b+ w3 j/ D5 A
s = String(100); // 好;显式转换& P9 H$ g- U$ O' S4 n& w7 v
s = "st"; // 好;此时允许隐式转换
7 z1 W' O, t" _) B) A9 t* E} |
zan
|