- 在线时间
- 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>
' V8 ^. G1 H8 |' o ^1 }(Danny Kalev发表于2004-12-28 11:01:04)</P>带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:
5 J3 }0 u9 |5 w0 Q) Y1 m, d* g4 G8 E; t- _) b; e
class C {
$ r, n a, ?. f, H4 u6 D* E: jint i;9 \; t8 N- @7 i7 `! g2 S# g
//.... t, K( t* U/ G3 g k. Q) |% k
public:0 `( e/ v: p: ?: ^% @
C(int i);//constructor and implicit conversion operator2 |, o4 B2 ?4 U
//as well
3 _/ x7 k( E/ K9 y};3 ^; ] b+ V" x! Q
2 i5 B5 c5 J- b2 }$ ?
void f() {( U4 s7 h2 ] g
- {6 }$ x. h. j- _. e7 Z( ]
C c(0);9 N9 b: \0 z) ~6 G3 j
) r3 q7 V" Z0 S8 r2 Dc = 5; //将 5 隐式转换为 C 对象,然后赋值
% q: u& l/ W9 u' N+ e$ t* J$ @3 X9 _& \
}
: ~1 s; l* V6 A9 w$ |% g3 F- c) u- ~0 [
编译器重新编辑上述例子代码,如下:
* D. f9 q# _' l! Y& |
$ r. c1 C- F7 `8 O6 f% A//////////////////////////////////////////////////////////////////////////////////////////3 h; ]. s- U' w+ g
//"c=5;" 被编译器转换成下面这个样子:
8 \- g! y K+ o1 M9 K! V/////////////////////////////////////////////////////////////////////////////////////////
% L3 \% y% |+ @6 G) e$ s1 J0 R( h
5 o& l z+ D$ b2 q4 ZC temp(5);// 实例化一个临时对象,' r% C; u( N, d# O
c = temp; // 用 = 赋值
& i6 J( Y' f0 ]$ L2 Ztemp.C::~C(); // temp 的析构函数被激活; Z& l! ?+ `: t) f0 ]3 k0 l; y
" D% b' @. M7 \在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:
& n+ @( b# i9 W9 A( g
. F( H- |( r1 C4 qclass String {$ @! x. e/ L' M+ A- C3 X* y' W5 z+ X4 t0 ?
int size;4 ~' T7 D$ w g9 R: q+ d# {+ B
char *p;: F- a% D6 B$ P1 W$ O
//..& m2 F# s* S8 E+ n: c- q b3 }& V
public:
- S$ h! P3 F& z. Q( m( \& G, r String (int sz); //这里不希望进行隐式转换操作8 Q6 k/ `9 s, }# g; v4 }7 u! L0 N
};3 o1 N2 L0 d' X# O$ p: H* T0 E
void f ()
: U r9 x# q1 \* N6 t( h$ _, s{
) |! e& N6 D I String s(10);
0 e# v- g5 u. f
9 D) j6 Y8 |7 n! y0 i1 u: Q. o& g // 下面是一个程序员的编码;发生一个意想不到的转换:
1 z8 K. U1 J. ~$ Y
% G: |5 O# f/ H: c' l. Z2 p/ Z- U s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
% d$ E1 G8 N7 @% D' Y3 k5 h}
" E0 t/ M- }, W/ w4 E9 n$ p N( `! _# }4 Z$ c
为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
N- F8 W: w7 \2 B( m1 I& M. e6 U. h( ?$ k/ O
class String {* c8 C$ J# S) H$ f& ]4 R Q
int size; ^$ w% l+ Y5 b# @
char *p;
5 |8 g _0 W* k% E$ U0 J//..
9 H- E3 a. O$ @: A7 |public:- z$ N9 a) H% g4 _ q
// 不要隐式转换
+ D% Q; t, e$ T1 o" b( C explicit String (int sz);
, g' u) ^$ A4 {8 ~# O, B5 v String (const char *s, int size n = 0); // 隐式转换
$ h; m2 k) Q. A& {& i" X3 b};% ^6 I; U$ Z3 b3 a* z
$ Q2 E2 N9 a, I+ uvoid f ()% M5 w a2 d: l3 C9 `- D
{ _- {+ `! [5 E
String s(10);( q- e& \3 B( n0 U( z# M
* Q0 Z3 y$ K0 R1 g; d9 @
s = 100; // 现在编译时出错;需要显式转换:
0 V$ h. d Q6 v7 k. _! v( z. k- S" M* h) z+ A( o
s = String(100); // 好;显式转换" E! ]3 s9 H4 d( O \
s = "st"; // 好;此时允许隐式转换) w, a- z0 X& j/ J# a: ^
} |
zan
|