- 在线时间
- 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>
9 v: Q2 z5 e& @7 g+ P. i2 m(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:) }5 P6 _# _- H g7 b! z/ v
0 r+ S- p3 _0 {. s* B4 n
class C { V. i0 V4 |* F, V8 M+ [
int i;
0 m- ^8 x% o) f5 }; t& f( I//...! T9 k% V7 d' @6 g
public:# Z& n. S5 W3 Q, M
C(int i);//constructor and implicit conversion operator& ]) D/ B2 u) [& q) ~
//as well
. \* v; D$ T4 H};
, A# C# y6 @3 H9 N/ [
. m8 K5 |0 `0 h; g1 D3 gvoid f() {( j& B" G, R7 G* P2 u2 J5 N4 D
5 P: o8 v. N* U" ^( I4 h" @* L
C c(0);; o% e7 t @/ R" K
" @5 n$ k* w1 J' [7 ]8 W3 e
c = 5; //将 5 隐式转换为 C 对象,然后赋值
1 K) W7 _3 K: G8 I' z
0 ^2 P$ |/ P: \. V' L+ Z3 C2 i, B, E9 J}
- c) O) p: i" I& @* \* w
" w8 i3 w- Y1 T, N) z4 T编译器重新编辑上述例子代码,如下:
4 ]' c' X1 Z9 X, R( p9 S5 \* F- F
/ p9 _5 Q$ j3 B2 I9 E( c* J* Z( f//////////////////////////////////////////////////////////////////////////////////////////
4 ]) S) j9 V# O2 b) y//"c=5;" 被编译器转换成下面这个样子:
+ {: T2 k1 C9 ^- A% O j) ?/////////////////////////////////////////////////////////////////////////////////////////
: q: U2 y, r# ^, m$ B3 g g8 M1 B- T( K7 O
C temp(5);// 实例化一个临时对象,
& k3 ?( ~9 R$ @( c% ` nc = temp; // 用 = 赋值
( ~ J8 }5 Y# B" Utemp.C::~C(); // temp 的析构函数被激活
6 ?7 a L, G) ^% O# H3 O' Y4 Z' X
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:" D" X4 Y( x7 V+ i4 p
" ]7 Y0 q6 i e' H
class String {- E$ x9 `1 Z' G
int size;
( |: v% m& a" c' Xchar *p;
" ?) X& s, }2 I. s, ]( d, u% `//..% G# z9 O+ e% o; y$ T
public:
' p/ X; E$ d9 L String (int sz); //这里不希望进行隐式转换操作
% h$ U5 T; V7 v$ W9 O& d};% F. y9 ]- C( K' B r/ O; [
void f () l" w1 G0 H6 t7 D
{
, i- k- @ W2 N. }) j String s(10);7 P9 ` J3 k' }1 S5 I4 G+ R
" t. r$ z5 g! N$ o // 下面是一个程序员的编码;发生一个意想不到的转换: O% P$ L$ v: d; d
. Y" [, L5 b7 Q
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s* V7 |5 q& K4 n4 ^
}
, }/ w3 p/ W( r( R( `
/ W/ C' S/ X4 p8 L为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:' [3 q' W. p+ M5 T4 [
: x6 |8 W2 \/ X" V ]- l6 r Jclass String {6 n7 K! r6 H) v3 {' X
int size;$ l' P7 Y- a. b& r
char *p;
3 N, t8 Q- e7 _6 L//..
7 f0 X5 E* C# C, I. Bpublic:! c' M/ n6 ]% j; m, w
// 不要隐式转换
2 r! @* w( \" {+ W& ^; J explicit String (int sz); 8 K( f9 n E1 B' n' ~* y0 l8 Y
String (const char *s, int size n = 0); // 隐式转换' ~1 N7 f- ]4 ~0 e% K
};5 S! L* D4 y- t" y/ Q. u( K* V
# N( f( q. T% A4 z9 A
void f ()" v1 u: L; y+ T7 Y' H3 i- W
{
: N% c- C# |/ z* F& x String s(10);
# s$ l9 y0 S* k3 V9 W
" E0 m8 X3 ^$ i1 z+ a- t s = 100; // 现在编译时出错;需要显式转换:
* V6 \' }- T( M7 l* w' h8 c/ [/ b/ {( z6 H3 x. b
s = String(100); // 好;显式转换% u9 ^( {! y9 b1 j: E
s = "st"; // 好;此时允许隐式转换% T% A# D- o0 U4 B' n2 N
} |
zan
|