前言 ~`ny@WD9
IxZb$h[
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 I:cg}JZ>|
]=pR
一、在union中存储对象 /YAJbr
+0Q,vK#j^
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? Fh$slow4!
yLE7>48
#pragma warning(disable : 4786) w >; L{
#include &ANP`=
using namespace std; n2B){~vE
')Y'c
class TestUnion MGS-4>Q#
{ Qn@Pd* DR
public: 'a6<ixgo0
TestUnion(long l):data_(l) O^Q7b7}y
{ nI.x
}; :Qt
int data_; 8,P-
7^
}; dP?Ge}
fxaJZz$o
typedef union _tagUtype_ Z<[<n0o1
{ \JEXX4%
TestUnion obj; m,i,n9C->
}UT; pKiZ)3U
N["W Ir
int main (void) nAIo{
F
{
s#~GH6/
return 0; 8BOZh6BV
} ,l YE
c/N@zum,{
"5R~(+~<@
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: >@xrs
&Mq~T_S
class TestUnion \>LnLH(
{ Q/uwQo/
public: g- AHdYJ
int data_; t7n(Qkrv
}; Q1d'~e
'. Ed`?<p
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! NX`*%K
v\16RD
二、类中union的初始化 9EDfd NN
9{k97D/
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: A1'hlAGF
u0aJu
#pragma warning(disable : 4786) <h%O?mkC
#include ]D[DU]K
gb
^?l~SS
using namespace std; M FTkqbc
J;_}lF9d@
class TestUnion X[`bMa7IB(
{ b2aF 'y/
enum StoreType{Long,Const_CharP}; EVp,Q"V]
union 3bk|<7tl
{ )[0T16
const char* ch_; f` =CpO*
long l_; @KX
\Er
} data_; (" LQll9
StoreType stype_; +a-6Q ~
TestUnion(TestUnion&); VE+IKj!VG0
TestUnion& operator=(const TestUnion&); &%})wZ+Dj
public: m'P1BLk
TestUnion(const char* ch);
J)P$2#
TestUnion(long l); JJ;[,
operator const char*() const {return data_.ch_;} zi`b2h
operator long() const {return data_.l_;} yFDv6yJ.
}; m_?d=o
06$!R/K
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) ST\$=
{ 0#w?HCx=
} "Rn3lj0
|D, +P
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) @d Jr/6Yx
{ nJ~drG}TD
} ;"(foY"L
Wu4Lxv]B4
int main (void) ?5_7;Ha
{ =FE|+!>PA
TestUnion pszobj("yuankai"); mM`wITy
TestUnion lobj(1234); 6-?66gmT
cout<(pszobj)< cout< K>*a*[t0Sy
return 0; V&-~x^JK
} M\yT).>z
fS~;>n%R
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: !9Aaj<yxm
T&Lb<'f
class TestUnion ^i:`ZfA#
{ (aD_zG=k5
enum StoreType{Long,Const_CharP}; !\&