- 在线时间
- 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>
$ K0 J+ w: C. J j) ?(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
( ]$ N1 Q# Q$ h2 n, b" P; H6 z! m. x# N3 Q4 }" G b. j1 Z5 S% h
class C {4 W% ? Z1 Q& m8 S4 v4 p2 r& b
int i;
! q, U! K+ r: b- q( q//...7 o8 d# S+ L4 `
public:# y4 A+ g# C* l$ ^
C(int i);//constructor and implicit conversion operator! ~. c3 ]5 K/ o' V6 p* Z
//as well
$ k* a# B' ^+ U8 N; b: A' j};
0 D' c7 b: k0 C% p3 `/ |: @# E, I7 Y; E( s, G8 t
void f() {- o# n6 Y! I2 T+ c$ S* I0 o8 u
. n& T8 ^) T$ a: _" B
C c(0);1 A1 t6 _: G, k" E% t" m* V" X" B
" k- u/ [6 z+ B. l0 {c = 5; //将 5 隐式转换为 C 对象,然后赋值; w6 @, l/ s q' I2 t* ^, s
' `8 n; {8 P7 c2 W5 I0 g/ k}
9 x/ y" Y9 K% k* @+ A; U+ v) s/ A' K0 }, t9 P! x+ @
编译器重新编辑上述例子代码,如下: $ c" P' a: ?; W/ f. i1 ^' X: c
; v9 H: s+ M3 Q
//////////////////////////////////////////////////////////////////////////////////////////
* r6 p+ y' b2 u D//"c=5;" 被编译器转换成下面这个样子:% r: p1 Q6 a' X: [/ f/ ^
/////////////////////////////////////////////////////////////////////////////////////////+ F+ C$ v$ {& L2 G( {
2 _7 Y V, y. F3 X5 y/ m" C7 r
C temp(5);// 实例化一个临时对象,* v& L, X# G/ i2 L' K
c = temp; // 用 = 赋值
( w( r: y8 g7 Y! Ztemp.C::~C(); // temp 的析构函数被激活) g" m( F$ G( O* c
$ Y( L K7 T' b8 {2 g: h5 R# V
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
. ^# D# Y5 a, M7 `. X, p9 L6 s$ O' |) w
class String {
9 y6 \+ T/ T, u- r) q5 \int size;
0 W# @6 N: \; y Uchar *p;1 `9 i' |9 F2 L0 ^ z" ^6 C8 q
//..
+ v8 C ]2 Q# M: k9 o: t% Wpublic:
% B- k: r& q" I F) ^5 A3 v2 g2 p4 ~ String (int sz); //这里不希望进行隐式转换操作0 P$ A* b# u- j0 O7 B
};
; T- E2 v8 p0 P; }void f ()" G- a* s, c4 V; X& Y. }
{) r- Y; ^) B3 @
String s(10);
& W h. Y; L/ }
5 q( ~; K. \1 Y* K" O$ K // 下面是一个程序员的编码;发生一个意想不到的转换:
/ X( t, z% d' J) Q0 s2 F: U. Z- q. ~+ y7 I
s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
. ^% B. [& v8 p5 s2 _6 C6 h}
2 _0 N; C$ p! Y% N5 s( @) O# O6 L
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:% K, X) a, H3 b7 G8 j+ d; W) h
: o1 v7 Z6 c% v5 r: Eclass String {
5 P) w4 n1 ]8 x( x3 P) Vint size;
; |: B( ?5 B3 R$ g" ^char *p;1 E, O' e1 N# X) W$ j0 k
//..
, ?+ z) y1 c6 p f# v7 X( vpublic:
3 T0 W! l* X5 w* \" i6 n // 不要隐式转换; M' z* U) F2 Y7 z" ^% k3 y
explicit String (int sz);
( @& ~& j: Y! I: S2 V String (const char *s, int size n = 0); // 隐式转换0 P8 d# O8 a9 S6 H$ N2 O* K# @. r+ ?
};/ @7 j3 T- A* \4 @! X
! k/ i& q0 [1 Z! ]
void f ()! W& i# @, |! f* O
{
x E: ?2 G4 ?0 ]: Z0 Z String s(10);3 K/ g0 G# ` o* l" k; b5 |) \
: s% x! K8 u6 N/ G" N+ o
s = 100; // 现在编译时出错;需要显式转换:7 R2 x. Y- r2 `3 [2 p3 _
$ D7 v6 t. \- G6 q0 _
s = String(100); // 好;显式转换0 C, U9 z; D' M+ m+ V- I6 M5 Z
s = "st"; // 好;此时允许隐式转换
9 v6 _8 d5 ]3 S} |
zan
|