前言 WW;S
m\4jiR_o
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 (G"b)"Qum
T.HI
$(d
一、在union中存储对象 EPr{1Z
U$pHfNTH
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? awXL}m[_!
=5LtEgHU
#pragma warning(disable : 4786) ;P _`4w3
#include SM:{o&S`
using namespace std; D;<Qm,[
_qmBPUx
class TestUnion ~]A';xH&
{ k-T_,1l{
public: \nx^=4*yk
TestUnion(long l):data_(l) /v;g v[
{ C
did*hxJ
}; o)?"P;UhJX
int data_; q[q#cY:0
}; KI$?0O
@}x)>tqD
typedef union _tagUtype_ \x x<\8Qr_
{ 5D]%E?ag
TestUnion obj; ~/\;7E{8!
}UT; 9GkG'
s iv
KXd
int main (void) .$4DK*
{ 'oEFNC9V
return 0; GA6Z{U{XS
} tB[(o%k
d+ih]?
!?ayZ5G([
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: #joU}Rj|
u3 ?+Hu|*T
class TestUnion $&k2m^R<
{ E[htNin.B~
public: 4^alAq^
int data_; PKfxL}:"8
}; =o _d2Ak
^=D77 jS
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! _ZD)#?
+B_q? 6pR
二、类中union的初始化 c.,:rX0S
rQ*'2Zf'<
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: ui7 0|
nUhD41GJ
#pragma warning(disable : 4786) -j]r\EVKS
#include `U!eh1*b
ED"5y
using namespace std; Y#{KGVT<
',6QL4qV/
class TestUnion
M5exo
{ 2v`VtV|B
enum StoreType{Long,Const_CharP}; V uJth
union zG@9-s* L
{ Ps<)?q6(
const char* ch_; {)ZbOq2
long l_; Zu\#;O
} data_; V>A@Sw
StoreType stype_; ILF"m;
TestUnion(TestUnion&); MJV&%E6{:{
TestUnion& operator=(const TestUnion&); 7x-k-F3
public: N iNZh;
TestUnion(const char* ch); '_r|L1
TestUnion(long l); YcRjbF,|6
operator const char*() const {return data_.ch_;} ?8! 4!P%n
operator long() const {return data_.l_;} '/;#{("
}; *-_` xe
A~nq4@uj
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) _\sm$ `q
{ UH%?{>oRh
} Cl<`uW3
q'+XTal
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) vxr3|2`
{ :XBeGNI*#
} -hp,O?PM
8,dCx}X
int main (void) 0NpxqeIDY
{ 1.yw\ZC\
TestUnion pszobj("yuankai"); _h@7>+vl~
TestUnion lobj(1234); &sJpn*W
cout<(pszobj)< cout< pVt-7AgW
return 0; 9S&6u1
} Mk|h ><Q"
'$1-A%e$1
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: %>xW_5;Z
&E {/s
class TestUnion 6$)Yqg`X
{ L V33vy
enum StoreType{Long,Const_CharP}; W|D'S}J
union DataUnion //不能匿名 g6QkF41nG
{ Gu*;z% b2
DataUnion(const char*); //声明const char*构造函数 XuR!9x^5
DataUnion(long); //声明long构造函数 7F\U|kx_
const char* ch_; s;8J= \9W
long l_; T"9`[Lzva
} data_; &ks>.l\
StoreType stype_; G0> 'H1 Z
TestUnion(TestUnion&); b4ORDU
TestUnion& operator=(const TestUnion&); NqhRJa63
public: R\0]\JEc
TestUnion(const char* ch); 1ZhJ?PI,9{
TestUnion(long l); :$/lGIz
operator const char*() const {return data_.ch_;} ;13lu1
operator long() const {return data_.l_;} (.%:Q0i1
}; |;rjr_I
$Xz9xzOR
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) kc~Z1
{//注意data_(ch),这里直接引用data_ !p&M,6
} GsqrKrbJ
ttZ!P:H2
TestUnion::TestUnion(long l):data_(l),stype_(Long) \e'>$8%T
{//注意data_(l),这里直接引用data_ Pm+H!x,
} JsfbY^wz
H -.3r
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) A3'i
-
{ qh F/iUE
} Om>6<3n
JWMIZ{/M
TestUnion::DataUnion::DataUnion(long l):l_(l) kwGj7'
{ m'aw`?
} .t"s>jq 1
'cH),~ z
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!