前言 ^CM@VmPp
L]Xx-S
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 uhnnjI
XiV
K4sD8
一、在union中存储对象 68w~I7D>
,aq>9\pi
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? J5O/c,?g
$P)-o?eer
#pragma warning(disable : 4786) |/c-~|%
#include C-@M|K9A'
using namespace std; W5e>Z&&
qsN_EMgbdn
class TestUnion .W$9nbly
{ 4~&X]/_'
public: fZS'e{V
TestUnion(long l):data_(l) R?,v:S&i7;
{ <0m^b#hdG
}; >WJQxL4
int data_; 6' \M:'<0e
}; wuxOFlrg
j|qdf3^f
typedef union _tagUtype_ ?' mP`9I
{ W5()A,R
TestUnion obj; EP<{3fy
}UT; ?B)e8i<[f
%&lwp
int main (void) QNv5CQ&
{ 53.jx38xS
return 0; T-lP=KF=
} Uqx@9z(
BZKg:;9
jq_4x[
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: jeO`45O
n=0^8QQ
class TestUnion u-bgk(u
{ ,J<+Wxz
public: w@YPG{"j
int data_; 3h%Nd&_9
}; 7|bBC+;(
YguW2R=6]
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! (KfQ'B+
cRCji^,KJ
二、类中union的初始化 O-pH~E
Oml /;p
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: kp!(e0n
iCGHcN^3
#pragma warning(disable : 4786) !Htl e %
#include Jy[rA<x$
M?<iQxtyb}
using namespace std; .:B0(4Mj
{K|ds($ 5
class TestUnion >MhZ(&iD
{ BLt_(S?Z`
enum StoreType{Long,Const_CharP}; : Q2=t!
union usu{1&g
{ X'%BS
const char* ch_; -]YsiE?r
long l_; pe).
} data_; _j{)%%?r
StoreType stype_; `r}a:w-
TestUnion(TestUnion&); f'7/Wj
TestUnion& operator=(const TestUnion&); /Tw $}8
public: *IF~ab2
TestUnion(const char* ch); EiDpy#f}
TestUnion(long l); V' i@N
operator const char*() const {return data_.ch_;} zxd<Cq>d
operator long() const {return data_.l_;} unnuSW#v=
}; 31M'71s
$bBUL C
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) CG J_k?h
{ M:d|M|'
} mZ3Z8q}%P
yM(ezb
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) x[BA <UNO
{ M0)ZJti
} 9I#a{%A:
%+#l{\z
int main (void) <~svy)Cz
{ Xg;<?g?k
TestUnion pszobj("yuankai"); '^O}`
TestUnion lobj(1234); D.a\O9q"&{
cout<(pszobj)< cout< <iH"5DEe
return 0; +K2HMf'
} 7E?60^Tve
goD#2lg
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: o?3C -A|
:Fh _Ya0
class TestUnion @)z?i
{ e;"%h%'
enum StoreType{Long,Const_CharP}; p}K+4z
union DataUnion //不能匿名 jCg4$),b
{ u)/i$N
DataUnion(const char*); //声明const char*构造函数 P`_Q-vu
DataUnion(long); //声明long构造函数 a+9_sUq
const char* ch_; X&@>M}
long l_; wLg@BSC.
} data_; }Py Z{yS
StoreType stype_; fq):'E)
TestUnion(TestUnion&); 0f5)]
TestUnion& operator=(const TestUnion&); S6_dmTV*
public: .g=D70
TestUnion(const char* ch); =;?Maexp3$
TestUnion(long l); x51xY$M
operator const char*() const {return data_.ch_;} =jU#0FAO
operator long() const {return data_.l_;} )M56vyo
}; aLQ]2m
!Pd)
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) u1Wixjd|
{//注意data_(ch),这里直接引用data_ :<1PCX2
} =RlAOgJ
>k~3W> D
TestUnion::TestUnion(long l):data_(l),stype_(Long) )S@TYzdAN
{//注意data_(l),这里直接引用data_ 1nE`Wmo.2
} "`[4(j
-t125)6 I
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 99b"WH^3$y
{ 1ZWr@,\L
} i*+N[#yp
XNl!?*l5?l
TestUnion::DataUnion::DataUnion(long l):l_(l) i[vOpg]J
{ Dd)L~`k{)
} NnY+=#j7L
O tR
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!