- 在线时间
- 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>
2 z: A" S9 R y(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
2 v U1 W+ b' r7 a m) G" }
- n! F) c% a1 |class C {
3 K. `5 F+ b0 d& A& ?, K2 s# aint i;
* J+ [: N1 s, U( F/ n8 G//...# k5 H4 C- M) [' \% a+ ?
public:3 s n, u$ J6 O1 ^" W
C(int i);//constructor and implicit conversion operator& r+ V: r- \ G' f. O* \
//as well3 U' |6 B/ v. C0 n" N) i4 g0 ^1 l7 {
};
; q( q' a( R: V9 `, V9 S0 G* w9 b* c- i0 h
void f() {! ]. g6 t+ e% E1 U+ |" R9 E
# h: ?4 K' Z% Y! G. j
C c(0);
$ Z$ {5 U9 K7 a7 F" S, j
6 H- ?7 d3 ]. b1 O) {c = 5; //将 5 隐式转换为 C 对象,然后赋值
- W3 Z: ~* `3 P* A6 u1 V
' w0 n5 i7 {/ ]* ~4 r}
4 L$ v* h5 }% F: u
. l+ _# |! A1 O- S r0 c编译器重新编辑上述例子代码,如下:
+ [, l+ [. `& A, A1 @
* c3 ?5 r' F/ c: \; i7 i7 m////////////////////////////////////////////////////////////////////////////////////////// u9 t+ E, z& C% {
//"c=5;" 被编译器转换成下面这个样子:, ?) s# V" o8 R; ~# ?) H) B3 `
/////////////////////////////////////////////////////////////////////////////////////////
, [: L% ? ?' O R0 m9 u% T
+ _9 G0 v: o& K, M; n v' vC temp(5);// 实例化一个临时对象,
+ q) \" p, _$ T! |c = temp; // 用 = 赋值
3 k8 L. ?) ]% _! `8 N7 mtemp.C::~C(); // temp 的析构函数被激活
: v9 K9 @4 X( H# B5 m) z+ r) ?9 N" \
在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
5 \. s: @1 K/ K8 F# d" B/ @! u% R, O0 Z. X" G2 Q0 ]! _' B
class String {% W$ r6 U8 A/ ~; q0 L
int size;7 h& @% P0 ~$ n% U, @
char *p;
; O/ T) W, L* g! x6 N//..
& `0 N4 e! ~5 r$ Rpublic:6 T) z' `6 K2 m! ?, z
String (int sz); //这里不希望进行隐式转换操作. g0 m1 B% ?0 Z) M
};
1 k" G' W4 ~- ^) m6 ~. ~. a& Jvoid f ()
; t% x8 r# G) f* U& Q{
- t v1 H @7 | String s(10);
2 f. H7 z: |. S1 p3 u( v8 q# t; i. [1 m( e1 Z# H7 y
// 下面是一个程序员的编码;发生一个意想不到的转换:
6 I# B% t& S8 V; |3 ?- |
& o }8 U- h, ~) b! \ s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
% O$ F3 t, ~9 L+ M# \} ' k1 }5 Z* D$ C# Q2 O! |
5 x* O N; s1 G6 Y! j" S* }# L
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
; S2 K* i# \$ w' \# F1 _3 Z5 ?% s" }1 Z- M8 v0 Z; W9 P
class String {
+ t* F3 ?# T m; Uint size;. x+ k* \- w( H g7 D4 O2 k' V
char *p;
' L7 m0 m- \) |' E) V//..
# ?$ G( |9 a+ }8 ppublic:
- j( {2 N M' N$ ~8 Q# ^ // 不要隐式转换, l4 z# q+ z, G, n! R% W9 [( W
explicit String (int sz); " K1 {2 n: G! i5 T# y5 a# X
String (const char *s, int size n = 0); // 隐式转换, s! @2 b* B' J9 ` D
};
7 B, L: J$ |7 J
6 ?+ _; x# \, Q" a0 P5 P9 {! {void f (): L3 ]. u# p$ I( u; U
{' M T. C# f, d5 V/ D
String s(10);
' m2 h+ ~4 \0 F' @* i& }8 s
6 F4 M8 @/ l. T: @- l! S$ i) h" ^ s = 100; // 现在编译时出错;需要显式转换:
8 s0 q4 U$ ?" ~0 e* I' P& z' l( A1 t1 k( ?" Z4 s3 I0 n3 v9 F
s = String(100); // 好;显式转换1 a* `0 v5 N3 Y. `
s = "st"; // 好;此时允许隐式转换2 I: K: L9 v: v1 g/ N. h/ z, ^
} |
zan
|