- 在线时间
- 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>" J! c, [& @ [/ s, r3 n# R
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
2 u6 Y) P1 B! l/ O. R+ f, a! M' T1 B2 a9 d
class C {
) a" y" p1 F4 y, d% t, ~int i;
" ^& `' b8 t; z' l. I//...2 B0 M8 c j7 M4 f, s
public:
& _* T2 g9 e# o- v: i2 o; S C(int i);//constructor and implicit conversion operator
- V4 B5 ]: Z2 o [- f7 h( ~+ Z1 N# \//as well
2 P: c. l+ w1 P% r};
3 ^( {5 L! V; g7 x9 _4 K3 r( i' Z) p# v, K7 Y
void f() {' p3 W+ A; O7 }$ h, o u
0 _) o+ G8 |+ H5 q
C c(0);
& m+ F! F0 B: E
( R; Z% n- W+ Q# `+ d. S7 R$ wc = 5; //将 5 隐式转换为 C 对象,然后赋值
1 P: L7 @" T; K8 L
% m, o- I' V% @3 T2 R. o; a3 c}
5 g3 q: D; ^$ N o/ y
) s: S, o- q3 P2 i3 w8 W编译器重新编辑上述例子代码,如下: 7 w0 S% d* z* u% s$ a+ v/ F" _# R
0 y+ t& r$ v9 k* p) p5 B" B
//////////////////////////////////////////////////////////////////////////////////////////
0 q! W' T) r9 O9 ?//"c=5;" 被编译器转换成下面这个样子:
4 L0 J4 Q$ ]+ ?1 R' b: g/////////////////////////////////////////////////////////////////////////////////////////; h0 `; z8 c2 G @5 |1 p4 h8 s* U# X- C
2 A; Z: V6 [1 S9 @% ~* G
C temp(5);// 实例化一个临时对象,- f4 N& g( x2 O
c = temp; // 用 = 赋值* K* F1 c3 K. m. I
temp.C::~C(); // temp 的析构函数被激活
f3 {1 X" x6 B9 B+ o9 } X* C
# n! k- D2 b8 a2 u在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
) t' ?- o7 r8 d5 a1 }
# ~4 J: o& G) k; [9 Kclass String {
( K5 q6 k' V) m" O+ H) lint size;9 p9 y6 H: E& g) A( j: G
char *p;" O. m" O4 A4 ^3 s/ ?/ `1 k6 W
//..
m% |6 }$ \* x! t& spublic:
1 |1 X5 F$ l. n+ t. z/ _ String (int sz); //这里不希望进行隐式转换操作% @* {9 F2 J8 M$ s+ k
};
) {. [' ?. D% n+ b- F) E4 x" Lvoid f ()
8 a) }: \1 U2 n7 h- E' H{
* d( U* w" p) G P, k E String s(10); {( F7 e. j" @4 L+ e) {
- o" |' R; T4 K/ }6 p // 下面是一个程序员的编码;发生一个意想不到的转换:1 v$ O: x! u. E9 w8 a$ ~% E
* F7 V: k# |/ U% V; s% q
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
R5 N2 t- ^: ~6 X7 D} : y# D, ]2 S" w1 N' n
/ ^8 f# `2 q7 Y+ w. k- w' r; [为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
; G4 p6 a# k! z8 H( c( I1 _2 j( V
class String {
' j# h: y* X! O2 |$ t' g* O; Uint size;
6 s! n, [7 z* c4 S x1 z/ X2 A8 T/ Qchar *p;
2 e6 y( E3 p. A! h( i//..
( F0 m% F. Q1 f$ w% }4 ^0 T3 Bpublic:% s: @3 X7 }% {" z2 Q
// 不要隐式转换! Y% s b, t# L: V+ I
explicit String (int sz); : ~( k. @9 T8 ]+ S- ]* V* w
String (const char *s, int size n = 0); // 隐式转换
4 f7 d' T1 a9 P. ]+ U. |};1 k/ Y n( `9 u5 M, i# @7 X
1 ?7 j) G" ~3 Q) w, i% h
void f ()
3 S+ W) [! B, w) ^{0 R+ v2 M/ A) y& n( S0 i
String s(10);
" G7 v0 E( q0 f9 W ^- z' N2 B9 d
s = 100; // 现在编译时出错;需要显式转换:
: ^) N& J1 v- r K( S, Z" u. a+ O! ~6 W) u% ~
s = String(100); // 好;显式转换
; A; h: `- e. [* A% I8 j s = "st"; // 好;此时允许隐式转换3 w& X# w Q) d& ~. R8 x% d7 E- o
} |
zan
|