前言 bTbF
~x6<A\
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 83g$k
9lG.
bK#SxV
一、在union中存储对象
GW\66$|
J`xCd/G
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 35/K9l5
`|WEzW~
#pragma warning(disable : 4786) p` /c&}
#include }C!g x6
using namespace std; :hFKmoy#
3:"w"0[K3
class TestUnion ~Y 3X*
{ i.Z iLDs\7
public: 20?@t.aMp
TestUnion(long l):data_(l) pi;'! d[l%
{ =:;K nS
}; WO!'("
int data_; iph}!3f
}; ?'RB'o~
lFZl}x
typedef union _tagUtype_ Q%!Dk0-)
{ %_%BbQf
TestUnion obj; E(g$f.9
}UT; FL E3LH
o8h`9_
int main (void) 7r o&Q%
{ pj#l s
return 0; Z~1uyr(
} uZe"M(3r$
6<mlx'
E4,
J"T|@
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: TE% i
J>8kJCh9g
class TestUnion 8e32NJ^k~
{ X+kgx!u'y
public: 3*= _vl3
int data_; /I &wh
}; DPr~DO`b
RmRPR<vGW
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ve^gzE$<I
yS1i$[JV
二、类中union的初始化 YF)k0bu&;
d<Dm(
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: / }Pj^^6A<
z)Lw\H^/
#pragma warning(disable : 4786) lKG' KR.
#include )fQ1U
'Y0h w
using namespace std; G j^*
lc\{47LwZ
class TestUnion aM+Am,n`@
{ qPBOt;N
enum StoreType{Long,Const_CharP}; )kD B*(?
union nrg$V>pD
{ 2p~}<B
const char* ch_; OJiwI)a9
long l_; lokKjs
} data_; b3Qk;yz
StoreType stype_; K<q#2G0{
TestUnion(TestUnion&); 6bN8}\5
TestUnion& operator=(const TestUnion&); !<>*|a
public: L7]o^p{g}Q
TestUnion(const char* ch); '0w</g
TestUnion(long l); i>O8q%BnJ
operator const char*() const {return data_.ch_;} Xo$SQ0K
operator long() const {return data_.l_;} mDx=n.lIz
}; ]=ADX}
RT|1M"?$
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) {krBAz&
{ "
v<O)1QT
} 9oYE
0D Lw
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) dhjX[7Bl9
{ SY.ZEJcv
} <nTZs`$LwL
zx5#eMD
int main (void) |DYgc$2pN
{ G=]ox*BY
TestUnion pszobj("yuankai"); V*DD U]0k
TestUnion lobj(1234); ?dPr HSy
cout<(pszobj)< cout< .N7<bt@~)
return 0; [&g"Z"
} ,0c]/Sd*p
pu5%$}dBE
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: IhRdn1&
zf>*\pZE
class TestUnion ;;6$d{
{ Lt
^*L%x
enum StoreType{Long,Const_CharP}; Gt)ij?~
union DataUnion //不能匿名 w' E(9gV
{ w{ ;Sp?Os
DataUnion(const char*); //声明const char*构造函数 rp+]f\]h
DataUnion(long); //声明long构造函数 ..zX
const char* ch_; {Fqwr>e
long l_; 5'( T*"
} data_; 33; '6/
StoreType stype_; QQHQ3\
TestUnion(TestUnion&); NcBz("
TestUnion& operator=(const TestUnion&); 4/%Y@Z5
public: nRvaCAt^
TestUnion(const char* ch); yj=OR|v
TestUnion(long l); \d*ts(/a*
operator const char*() const {return data_.ch_;} \~g,;>%7Y
operator long() const {return data_.l_;} 'iTY?
}; c8Q}m(bhWI
Xmi~fie
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) qV;I<AM
{//注意data_(ch),这里直接引用data_ 9J?lNq
} /EG'I{oC
o".,JnbXl
TestUnion::TestUnion(long l):data_(l),stype_(Long) '4_c;](W
{//注意data_(l),这里直接引用data_ >bd@2au9!
} ~sZ$`t
y+Hz(}4
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) D(OJr5Gg
{ 1$+8wDVwad
} @+l=R|
J?EDz,
TestUnion::DataUnion::DataUnion(long l):l_(l) 8t. QFze?
{ I&m' a
} o2'Wu:Y"
8N+T=c
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!