前言 {t&+abY
kR|(hA,$N
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 #ui7YUR=2
;/<J.
一、在union中存储对象 v0S7 ]?_
ShRkL<
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ];G$~[
pM7xnL4
#pragma warning(disable : 4786) jRzQ`*KC#
#include B=J/HiwV)
using namespace std; D1<$]r,
t"Djh^=y
class TestUnion j 1#T]CDs
{ k84JDPu#
public: -YP>mwSN?
TestUnion(long l):data_(l) 9{V54ue;
{ t=oTU,<
}; gEQevy`T%c
int data_; Cn(0ID+3f
}; @ 6{U*vs
ce P1mO
typedef union _tagUtype_ *ocbV`
{ >VWH
bo
TestUnion obj; aj*%$!SU+
}UT; zMQ|j_l9E
^YG.eT6iG
int main (void) Ws(#ThA
{ S[W|=(f9
return 0; {,rVA(I@
} #s'
-KG3_k E
)51H\o
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: 8y,
]>n
="*8ja-K
class TestUnion 3xnu SOdh
{ |k^ *
public: 4?{e?5)
int data_; " |l-NUe
}; ,:QDl
BnLWC
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! N2^B
saaN$tU7
二、类中union的初始化 0jN?5j
Kq0!.455
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: c0%%X!!$
]o]*&[C
#pragma warning(disable : 4786) cCH2=v4hU
#include X%._:st
P$= Y 5
using namespace std; yy6?16@
/n SmGAO
class TestUnion gnp\z/'>
{ 4X &\/X
enum StoreType{Long,Const_CharP}; :3x |U,wC
union Q0j$u[x6s
{ ^L1#
const char* ch_; L)o7~M
long l_; g.d%z
} data_; g qRwN p
StoreType stype_; )R2BTE:
TestUnion(TestUnion&); Vuqm{bo^
TestUnion& operator=(const TestUnion&); R)w|bpW
public: B^SD5
TestUnion(const char* ch); V3u[{^^f
TestUnion(long l); 6DG:imGl
operator const char*() const {return data_.ch_;} 'B>%5'SdD
operator long() const {return data_.l_;} p ft6
@'q
}; 1wa zJj=v
hd2 X/"
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) I!ykm\<
{ bVc;XZwI
} |&t 2jD(
ui:
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ^c{,QS{
{ '}{J;moB
} N'nqVYTU
,/;mK_6
int main (void) U8z$=Wo
{ I%NPc4p
TestUnion pszobj("yuankai"); YolO-5
TestUnion lobj(1234); -m:i~^
u
cout<(pszobj)< cout< Jn>7MuG
return 0; `!j|Ym
} v^h
\E+@
P/'~&*m-
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: cia4!-#
I"]5B
class TestUnion JxP=[>I
{ XK
(y ?Y1
enum StoreType{Long,Const_CharP}; l0 H,TT~2
union DataUnion //不能匿名 3 G?^/nB
{ ?5qo>W<7
DataUnion(const char*); //声明const char*构造函数 RrkS!E[C
DataUnion(long); //声明long构造函数 l+.E'
const char* ch_; /]Fs3uf
long l_; *@q+A1P7@
} data_; QM1-w^
StoreType stype_; QJ`#&QRp
TestUnion(TestUnion&); \:8 eN}B
TestUnion& operator=(const TestUnion&); '|b {
public: FBM 73D@`
TestUnion(const char* ch); T{={uzQeJJ
TestUnion(long l); u":D{+wC|
operator const char*() const {return data_.ch_;} Ey77]\
operator long() const {return data_.l_;} g<