- 在线时间
- 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>4 K' e6 J; W1 F) q; P' p
(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
: p4 E3 n" g) ?$ G# j3 [7 J. n5 X, t7 c
class C {
/ u2 ~: L1 B* f8 W3 ]3 Pint i;
! J$ o3 ]. x8 R _% Z6 E//...$ F% G3 `/ [6 ~& ^& c9 I
public:
7 \" d% z: ^. `3 l C(int i);//constructor and implicit conversion operator% `, L- T$ x# |; c/ t4 \
//as well% G8 ^4 s& P( e# F6 n* _! [
};9 ~1 U' Y5 |3 Z" n
- @: o) j9 |2 X Cvoid f() {
' \, r$ n" O) T. x* c; E9 E6 x5 {* U; x) _. A. f9 u
C c(0);" A+ t2 W) j9 S0 v1 W% l
0 k# u) p [! w& N3 M* ^' sc = 5; //将 5 隐式转换为 C 对象,然后赋值# Z* Y, k5 I5 |) k
0 v8 b( U2 v4 X, f X
}. W |/ I" {4 Y2 X6 X, C
' d; V, S" N! f4 S. Q2 w! d# e编译器重新编辑上述例子代码,如下: $ }4 s8 C$ ?% J( s, S) C! f/ G
7 \9 f! |4 k& [7 P* W
/////////////////////////////////////////////////////////////////////////////////////////// D2 B7 G7 D9 d0 T1 H8 c# O P
//"c=5;" 被编译器转换成下面这个样子:5 u) g% \% y7 q7 Q% \9 e, E
/////////////////////////////////////////////////////////////////////////////////////////; K8 a& J. W5 Y e
$ u& a$ T) r2 Y" E8 j) HC temp(5);// 实例化一个临时对象,5 ]7 s3 U# P- {; i3 X: ~1 K' N
c = temp; // 用 = 赋值( J' z; y% Z# U5 N) z* d' U" G0 P2 E
temp.C::~C(); // temp 的析构函数被激活
$ ?: k* b% m6 i% p( h c
5 [2 v, i Y; L+ a. u在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:3 F1 w( [* n) ]' p, q D: E
6 J I, s4 w8 [class String {3 P. O3 s+ X* ~: e& U* l& \5 R6 M
int size;% J- I# ^7 S. t. R- t1 h7 n% z
char *p; e; e* O' R/ Y5 L
//..
& {$ ~+ B4 z, Y. V/ Fpublic:
/ s- Z0 T; C3 y- Z, S9 B* w String (int sz); //这里不希望进行隐式转换操作 M& v6 y* w' ~
};% x; _/ `- p/ m+ k" E' e
void f ()8 t& H* Q3 l N8 L2 D. d, }
{- f( e) D/ y" \$ Z
String s(10);1 M; `+ p' O" z+ _7 Y% f
- z% C. Z0 X! G# v* [7 [0 k
// 下面是一个程序员的编码;发生一个意想不到的转换:. j9 [$ W% E% Y! Q- m3 m) `. ^& E
! J! L4 E. k6 X9 f) t" A s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s. `. w8 t) N+ \" [" X
}
1 A% V8 g7 W5 P
$ l& P+ K# @$ S% i' M* P {. A为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:# S0 O2 _. U- _9 G
( k- Z5 K% J- d4 {8 f6 cclass String {8 H3 t$ h) H! L* q: E$ |/ g6 ?
int size;
1 P1 e7 L v: Y! k1 G0 d# Achar *p;& J5 B b/ j. F
//..! K9 `7 l! I$ I
public:
* C6 X( D% [2 u5 f // 不要隐式转换
# V, m* s, b# x. ~ explicit String (int sz); ' o: J/ T& Q7 x: h+ ^
String (const char *s, int size n = 0); // 隐式转换
S8 `6 q3 s4 C1 L# B# o, U};
( }9 O6 @: u4 M" y- Z- F. U& u3 X/ J' a! E4 H2 b7 f; O
void f ()
% Z5 s( q1 ^- @/ V* _. p: n{
, n2 i& B3 x, e String s(10);
/ |2 {7 G9 B* Z; A) ? n
8 v9 g" k8 j. J B( H0 F. T0 T s = 100; // 现在编译时出错;需要显式转换:! T! s0 R7 Q( d
" i, L$ u/ M0 g2 X' W" A s = String(100); // 好;显式转换
: ^$ j: M* Z4 n: t6 @ s = "st"; // 好;此时允许隐式转换$ M( e! t' L% O8 x6 n
} |
zan
|