前言 EcR[b@YI
qIy9{LF
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 ] RVme^=
O" [#g
一、在union中存储对象 .(Z^[C}
"|WKK}
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? d.>O`.Mu)}
8M['-
#pragma warning(disable : 4786) tuo'Uk)
#include :K \IS `
using namespace std; zyK11
tQMz1$
class TestUnion A,#z_2~
{ dDYor-g>
public: : T4ap_Ycq
TestUnion(long l):data_(l) p8CaD4bE
{ 1
!.PH
}; I=E\=UTG,5
int data_; nwDW<J{f|U
}; ^sJp!hi4=)
z.t,qi$;{U
typedef union _tagUtype_ .p~.S&)
{ x;7p75Wm
TestUnion obj; esv<b>`R
}UT; `1
Tg8
5B{Eg?
int main (void) ,+5!1>\
{ &4p~i Z
return 0; Ys5Iqj=mp
} 1x0)mt3
;UQ&yj%x
TU2MG VYy
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: Pi[(xD8
eYg0NEq{
class TestUnion iqTmgE-
{ Ban"H~
public: XOZ@ek)LY
int data_; \7(OFT\u:
}; )d5mZE!3
*u34~v16,
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! 4Gh%PUV#
51>OwEf<R
二、类中union的初始化 ,v*\2oG3^
U,`F2yD/!
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: KXo[;Db)k
;p(Doy)i
#pragma warning(disable : 4786) BLo=@C%w5
#include Fz$^CMw5K
W$R@Klz
using namespace std; {f>e~o
Ys%d
class TestUnion x1`Jlzrp,
{ Wc/B_F?2
enum StoreType{Long,Const_CharP}; Dd,]Y}P
union [4}U*\/>C
{ .18MMzdN
const char* ch_; ];Bk|xJ/>
long l_; qS[nf>"
} data_; kPp7;U2A
StoreType stype_; 6)3pnhG9
TestUnion(TestUnion&); 74~%4
TestUnion& operator=(const TestUnion&); Xu[A,6
public: o l+*Oe
TestUnion(const char* ch); SM`n:{N(
TestUnion(long l); .ffb*gZ4
operator const char*() const {return data_.ch_;} W%}zwQ
operator long() const {return data_.l_;} YR~)07
}; sTYA
<(o) * Zmo
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) z`y^o*qc]
{ ){i
9,u")
} u+]8Sq
i"y @Aj!7
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) :AC( \
{ j{NcDepLn
} `c_Wk]i
{X&H
int main (void) meyO=>
{ I6 Q{ Axy
TestUnion pszobj("yuankai"); :W1B"T<
TestUnion lobj(1234); nA#dXckoc
cout<(pszobj)< cout< :\G`}_db'
return 0; xR5zm%\
} "[\TL#/
?xCWg.#l4V
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: #6Fc-ysk:
140_WV?7
class TestUnion y gTc
Y
{
m3 Rss~l
enum StoreType{Long,Const_CharP}; D3;#:
union DataUnion //不能匿名 p!~V@l
{ mp>Ne6\Tu
DataUnion(const char*); //声明const char*构造函数 ,A!0:+
DataUnion(long); //声明long构造函数 p+1kU1F0
const char* ch_; 'di(5
long l_; Eg#WR&Uq"
} data_; ksli-Px
StoreType stype_; e:RgCDWL
TestUnion(TestUnion&); XRWy#Pj
TestUnion& operator=(const TestUnion&); m2PI^?|e
public: 10e~Yc
TestUnion(const char* ch); 1ihdH1rg[
TestUnion(long l); [-JU(:Rh
operator const char*() const {return data_.ch_;}
i(n BXV{
operator long() const {return data_.l_;} &\M<>>IB
}; QetyuhS~
Gmh6|Dsg
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) 2lRE+_qz
{//注意data_(ch),这里直接引用data_ 7,Q>>%/0P
} =$Sd2UD
Q)\4 .d
TestUnion::TestUnion(long l):data_(l),stype_(Long) p6W|4_a?
{//注意data_(l),这里直接引用data_ `-82u :"
} J0x)NnWJ
Meo.
V|1
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) p u6@X7W"
{ pK@8= +
}
i}r|Zo
<Is~DjIav
TestUnion::DataUnion::DataUnion(long l):l_(l) tx||<8
{ ! $8 e6
} rE$=~s
~k'SP(6#C
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!