- 在线时间
- 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>
" {& T' ^2 U5 R7 a- w$ {$ K9 {" T(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:" A4 L2 _7 b- W( m, x2 \# s2 M
# _, u- S0 U, ?class C {
) v& P5 X$ l2 M7 e0 W' {int i;/ B8 K- ^& Z: m: \9 r, ~
//...
) R' y2 l+ D2 I6 q9 F$ {8 upublic:
" q0 H7 D: o* m, _ C(int i);//constructor and implicit conversion operator8 X8 M; `1 v" Y) o2 b i5 S$ g! X
//as well+ ?& |- k: s$ |% F. Z# B, g
};
2 ~- w0 d3 f4 u, v
5 S/ L; G9 @3 L( _void f() {( ?: d: @- s7 u/ }; ~6 V0 h# X0 B
x; z3 H Y6 ?; Y' J
C c(0);
9 {# g8 K; ?0 D1 l5 t
8 }6 a: ]5 [$ y6 b& Wc = 5; //将 5 隐式转换为 C 对象,然后赋值
* y; e ~" d- b+ I% d' J7 Z
, q5 m* G3 Z1 {! U}$ T: o2 T: ?1 c
) s5 O$ X% d6 T9 y3 T$ `5 Q2 i编译器重新编辑上述例子代码,如下:
u5 {: F: C/ |$ k
) e7 F4 x5 Y! o3 e5 Z3 }* d//////////////////////////////////////////////////////////////////////////////////////////
, s/ [9 ]0 O& a/ u//"c=5;" 被编译器转换成下面这个样子:" F3 b; {4 M* F2 ]( q' M
/////////////////////////////////////////////////////////////////////////////////////////$ k0 I' D; M- a- B' K5 P
- T' {, G% D* N# e' X- Y. QC temp(5);// 实例化一个临时对象,
, v+ a3 @/ G1 _c = temp; // 用 = 赋值
9 U: F# p+ z* g" j; l' ^5 ^temp.C::~C(); // temp 的析构函数被激活- P6 b+ A. V% N1 |* [/ m1 a
+ p f9 R3 n+ |3 ^6 y( B
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:6 C% `) n: V( Z
$ P' E( B/ I7 k9 L% g
class String {( f5 M# L" R7 L6 n+ U9 `! V7 n
int size;
0 b" ~- a# }8 S& dchar *p;
5 x C# r+ F2 a0 G//..$ F1 q6 o9 v! T* y, j
public:
& b. {; [, ~# Y. P ] String (int sz); //这里不希望进行隐式转换操作
( m6 X7 \' z, ~4 W};
% h7 Z8 U) [' R; U+ \+ Mvoid f ()
- O( U2 s/ c9 G8 }' W{$ V+ Y5 n1 Q, d! b$ b9 x1 u
String s(10);* d2 o, X3 s4 U( b, W0 d# @
4 p& f% a/ V1 L2 P // 下面是一个程序员的编码;发生一个意想不到的转换:2 w4 r* T6 P& U' w+ r; G f$ x
8 L+ H; Y# c) D3 G$ f6 x
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
( G& b/ u y h. v1 u) I}
; P- ~$ K) q- ]' ?/ z7 Y
, a" _" k3 p) i0 z! X% ~( [为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:: f! p/ _4 I) d( L2 k. x
- w% o* j5 U1 a" _
class String {
1 c% K( a0 c; o0 l3 bint size;
9 ]0 z. R6 W% f% F$ j( Ichar *p;
( a, S2 x8 u( O) d2 }- Z! d//..+ \9 ^& U4 j: V/ G
public:
c# l9 S% ?7 { // 不要隐式转换
4 l. i9 \! M6 ~: C; ]8 f' A4 N explicit String (int sz); 0 j# ]" F4 h2 X5 \; V; N5 a
String (const char *s, int size n = 0); // 隐式转换! H( Y7 A! I1 p& G# N
};
1 k/ w7 G' {: f" P8 Z5 d! i3 }, H! O8 _ g0 c3 m u3 `& e: r, N7 ]5 K
void f ()
! a+ F* P7 u* J# N/ F5 k) _1 g1 M5 \{
9 e; C1 z% J. H* r% k String s(10);
1 g, n8 F& V; c2 g# Z0 U& _
, U6 f( F9 U8 S& G s = 100; // 现在编译时出错;需要显式转换:
q% ]) x# Y9 P5 `
9 P) V* j. t9 B1 J s = String(100); // 好;显式转换
" ~! v1 _. {2 J! s, f/ x s = "st"; // 好;此时允许隐式转换
/ V% |6 \4 o5 [2 W9 a1 X% q} |
zan
|