前言 kb\\F:w(W
2%-/}'G*
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 RRpCWcIv"
yx<-M
一、在union中存储对象 4^^=^c
jU{~3Gn?
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 94lz?-j
~'Korxa
#pragma warning(disable : 4786) US<l4
#include
S O`b+B
using namespace std; AgOti]`aR
C)cuy7<
class TestUnion i2)$%M&
{ +WCV"m
public: L7yEgYB
TestUnion(long l):data_(l) F~GIfJU
{ OFZo"XtF
}; *b`1+~p_2
int data_; &<(&u`S
}; 'qoaMJxN`
bW GMgC
typedef union _tagUtype_ Rf!$n7& \
{ j9f Q V
TestUnion obj; m-9ChF:U
}UT; m>DJ w7<
SS&G<3Ke
int main (void) @f#6Nu
{ k4JTc2b
return 0; ^HWa owy=
} .p78
\T
Hr(%y&0
Dyj>dh-
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: +@+*sVb
);xTl6Y9
class TestUnion gZL,xX
{ DLoH.Fd
public: FY,)iZ}Pq
int data_; A ?[Wfq|
}; MwD8a<2Dg
LKM;T-
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! >B$B|g~
MVDy|i4
二、类中union的初始化 X(;WY^i!
<@>l9_=R
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: }4q1"iMlO
N3\vd_D(
#pragma warning(disable : 4786) T=[/x=
#include u y13SkW
nR,QqIFFw
using namespace std; }Rq{9j,%
/kqa|=-`q
class TestUnion xH>j
{ 4@9xq<<5
enum StoreType{Long,Const_CharP}; eY`o=xN
union &Y2Dft_K
{ "BC;zH:
const char* ch_; :d|~k
long l_; @lCyH(c%
} data_; %vRCs]
StoreType stype_; 9bUFxSH
TestUnion(TestUnion&); +6(\7?
TestUnion& operator=(const TestUnion&); 4mm>6w8NT
public: |0VZ1{=*
TestUnion(const char* ch); +-Z `v
TestUnion(long l); Bh65qHQO
operator const char*() const {return data_.ch_;} E_#?;l>
operator long() const {return data_.l_;} rs0Wy
}; ^K:-r !v^
,-SWrp`f
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) \$xj>b;
{ AK&=/[U>
} 6P02=
PeJIa
%iE
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) !WTL:dk
{ ?DKY;:dZF
} xks Me
2k^'}7G%
int main (void) |Zdl[|kX
{ [G"Va_A8
TestUnion pszobj("yuankai"); 5Rae?*XH
TestUnion lobj(1234); yVyh\u\
cout<(pszobj)< cout< pL,l
return 0; A(+%DZ
} aqv'c
j>
[=^Wj`;
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: Yb%#\.M/y
vU9:`@beu
class TestUnion L fZF
{ U,Fyi6{~
enum StoreType{Long,Const_CharP}; ^`bMFsP
union DataUnion //不能匿名 c-ql
{ D"&Sd@a{
DataUnion(const char*); //声明const char*构造函数 6>z,7 [
DataUnion(long); //声明long构造函数 /Edq[5Ah
const char* ch_; 0@Z}.k30
long l_; FzG>iC}
} data_; %RzCJxT
StoreType stype_; EKEJ9Y+47H
TestUnion(TestUnion&); 'i4L.&
TestUnion& operator=(const TestUnion&); cVDcda|PE
public: bP&1tE
TestUnion(const char* ch); N t\ZM
TestUnion(long l); VPb8dv(a3
operator const char*() const {return data_.ch_;} Qw<&N$
operator long() const {return data_.l_;} LHSbc!Y'.
}; JB'XH~4H
@I#uv|=N
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) }d%Fl}.Ez
{//注意data_(ch),这里直接引用data_ 9^@)R
ED
} bbT$$b-
DTHWL
TestUnion::TestUnion(long l):data_(l),stype_(Long) \susLD
{//注意data_(l),这里直接引用data_ \J(kM,ZJ
} uc/W/c u,
|mcc?*%t8
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) pk0{*Z?@
{ ^%!#Q].
} 0e1-ZP CDj
~EU\\;1Rmq
TestUnion::DataUnion::DataUnion(long l):l_(l) WWATG=
{ #\\|:`YV
} L[!||5y
.AZwVP<
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!