前言 /yK"t<p
zh?4K*>.k
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 /2w@K_Px6
qX@9N=g`#O
一、在union中存储对象 w6U
@tW
#O|lfl>}
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 8ui=2k(
TG]}X\c+V|
#pragma warning(disable : 4786) nEVbfNo0
#include JD&U}dJ
using namespace std; #:
hVF/
)0|):g
class TestUnion /co%:}ln
{ j`9Nwa
public: BTs0o&}e
TestUnion(long l):data_(l) "_)|8|gN
{ #JS`e_3Rr
};
SsRVd^=;x
int data_; JN^bo(kb
}; k /^g*
_80ns&q
typedef union _tagUtype_ vf_OQ4'G,
{ t?.\|2
TestUnion obj; u\5g3BH
}UT; d$Em\*C
{G.jB/
int main (void) Z:^3Fm->+
{ ^srs$
w]
return 0; Mdm0g
} >)sqh ~P
F(0Z ]#+
u_Zm1*'?B
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: T9y768%
uN(b.5y
class TestUnion L]>4Nd
{ xN"wF-s4?
public: {Y"8~
int data_; ||f vKyKW>
}; Q
3X
cuMc*i$w!
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! &CO|Y(+
}{=8&gA0
二、类中union的初始化 /&QQ p3
x_|>n<Z
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: qOgtGN}k
bQV("~#
#pragma warning(disable : 4786)
2$)mC9
#include <4$YO-:E
x
Ty7lfSe
using namespace std; PvuAg(?
*k[kV
class TestUnion _Z.;u0Zp8
{ khS/'b
enum StoreType{Long,Const_CharP}; /x
O{
.dr
union Vku#;:yUb^
{ Un\Ubqi0
const char* ch_; \gP. \
long l_; /pU|ZA.z'2
} data_; i\vpGlx
StoreType stype_; Z?C4a}
TestUnion(TestUnion&); w Oj88J)
TestUnion& operator=(const TestUnion&); >\&= [C
public: NkoofhZ
TestUnion(const char* ch); W/a,.M
TestUnion(long l); 7y>(H<^>
operator const char*() const {return data_.ch_;} pMDH
operator long() const {return data_.l_;} {70Ou}*
}; ~K%k
0kT
Md?acWE*L
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) t#{x?cF
{ kMqD
iJ
} H8sK}1.
,b4~!V
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) MyqiBGTb
{ XUf7yD
} mDlCt_h
W0U`Kt&~a
int main (void) /t$*W\PL@
{ niQ+EAD
TestUnion pszobj("yuankai"); i<bxc
TestUnion lobj(1234); 5U3qr*/ ;m
cout<(pszobj)< cout< J+0/ :00(
return 0; )FV6,
} 1O23"o5=
)ph30B
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: oFb\TiLu
&b!vWX1N
class TestUnion *^ey]),f54
{ gU u&Vy\
enum StoreType{Long,Const_CharP}; =#b4c>
union DataUnion //不能匿名 QYH."7X
>
{ t z"5+uuu
DataUnion(const char*); //声明const char*构造函数 4p?+LdL
DataUnion(long); //声明long构造函数 @|E;}:?u
const char* ch_; ~K_ ]N/ >
long l_; f!mE1,eBEe
} data_; n$IWoIdbGN
StoreType stype_; L!?v BL
TestUnion(TestUnion&); FoQ?U=er
TestUnion& operator=(const TestUnion&); dZ.}j&ZH'
public: D8gQRQ
TestUnion(const char* ch); A\Lr<{Jh
TestUnion(long l); K?$9N}+
operator const char*() const {return data_.ch_;} ;A
x=]Q
operator long() const {return data_.l_;} $^]
9
}; ;tXB46
3L?WTS6(u
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) )o86lH"z
{//注意data_(ch),这里直接引用data_ e',hC0&S
} H]Y#pLu|
0W;q!H[G
TestUnion::TestUnion(long l):data_(l),stype_(Long) j~Xj
{//注意data_(l),这里直接引用data_ ,\BfmC_i
} ( P
0@o;|N"i
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) ww-XMz h
{ q2[+-B)m
} :yd=No@
}*xC:A%aS
TestUnion::DataUnion::DataUnion(long l):l_(l) luJ{Iq
{ 8W(<q|t
} jK&
Nkp
rdORNlK&
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!