前言 LT,zk)5
C^U>{jf !
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 q="ymx~
+= gU`<\
一、在union中存储对象 we*E}U4
>w\3.6A
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 7vGAuTfi/@
Yc5)
^v
#pragma warning(disable : 4786) EF 8rh
#include ]`h@[fYge
using namespace std; %5Elj<eHZ
d1*0?G TT
class TestUnion 0\"]XYOH
{ <
r b5'
public: +tYskx/
TestUnion(long l):data_(l) EzCi%>q
{ YsTF10
}; 4QNwu7TeR
int data_; 4!'4 l=jO
}; >DzW OB
'^2bC
typedef union _tagUtype_ `j.-hy>s
{ 8D^ iQBA
TestUnion obj; |hu9)0P
}UT; v:9Vp{)
MP
Q?Q]'
int main (void) LN'})CI8m
{ ET6}V"UD
return 0; 3|/zlKZz
} pM!cF
<2I<Z'B,e
0{Zwg0&
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: = o1&.v2j
nC9xN
class TestUnion :+fW#:
{ uH)v\Js
public: ;,B $lgF
int data_; 0qN?4h)7
}; yfAh=
Hegj_FQ
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! !T]bz+
~llw_w
二、类中union的初始化 jrYA5>=>#
0IbR>zFg.
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: xw1n;IO4
U,~Z 2L
#pragma warning(disable : 4786) sbFA{l3
#include nh"LdHqiDB
%#lJn.o
using namespace std; F
@Wb<+0
il:RE8
class TestUnion vH?3UW
{ CX>QP&Gj
enum StoreType{Long,Const_CharP}; <gY.2#6C\%
union dJmr!bN\;
{ Z&J.8A]L
const char* ch_; Gii1|pLZ1
long l_; x.U:v20`
} data_; w"E.Va
StoreType stype_; ?)/&tk9.n
TestUnion(TestUnion&); 82=>I*0Q
TestUnion& operator=(const TestUnion&); mH4Jl1S&
public: 59a7%w
TestUnion(const char* ch); Jn1(-
TestUnion(long l); 0tN/P+!|
operator const char*() const {return data_.ch_;} p=f8A71
operator long() const {return data_.l_;} _^] :tL6
}; &8Oy *'
XZpF<7l
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) |%Ssb;M
{ Ky[-ZQQo=5
} <cR]-Yr~
*W1:AGpz
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) e5m-7{h@
{ /A%31WE&1
} DI:"+KMq{
roWg~U(S
int main (void) 2?9gf,U
{ Y:K1v:Knw
TestUnion pszobj("yuankai"); P%kJq^&
TestUnion lobj(1234); "]1|%j
cout<(pszobj)< cout< 2c8e:Xgv
return 0; 7@9R^,M4:
} h#I]gHQK
fBt`D
!Z8
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: $3:O}X>
f\M;m9{(
class TestUnion xw83dQ]}^
{ !"
7ip9a
enum StoreType{Long,Const_CharP}; sQr
|3}I(
union DataUnion //不能匿名 ]`O??wN
{ #p|7\Y
DataUnion(const char*); //声明const char*构造函数 3Qoa?*
DataUnion(long); //声明long构造函数 ZHOh(
const char* ch_; tCP;IU$
long l_; D TSK*a `
} data_; 'wP\VCL2>
StoreType stype_; a*KJjl?k
TestUnion(TestUnion&); pksF|VS
TestUnion& operator=(const TestUnion&); )\Ay4d
public: W{*w<a_`
TestUnion(const char* ch); sRf?JyB
TestUnion(long l); OLgW.j:Ag
operator const char*() const {return data_.ch_;} [n9X5qG~
operator long() const {return data_.l_;} c27\S?\
Jd
}; AU/L_hg
a2`|6M;
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) jM|-(Es.)
{//注意data_(ch),这里直接引用data_ d"hW45L
} hS 7o=G[
-PH!U Hg
TestUnion::TestUnion(long l):data_(l),stype_(Long) aYPD4yX"/
{//注意data_(l),这里直接引用data_ H+2m
} t"L-9kCM
\>GHc}
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) p7d[)*
L>C
{ *^-~J/
} n*GsM6Y&
bpWEF b'f
TestUnion::DataUnion::DataUnion(long l):l_(l) !Won<:.[0
{ Lb%Wz*Fa%!
} uS,XQy2
VsMTzGr
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!