前言
UjI./"]O
[P
&B
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 _d]{[&
p4t
^
8 }P_
一、在union中存储对象 1eD#-tzV
< o?ua}
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? }_nBegv
\p(S4?I7
#pragma warning(disable : 4786) >%tP"x{
#include 7Mh'x:p
using namespace std; L<!h3n
$mPR)T
class TestUnion VeWh9:"bJ
{ h>`[p,o
public: 9
Zo s;
TestUnion(long l):data_(l) ArtY;.cg%
{ rN&fFI
}; 6]1RxrAV
int data_; 16AlmegDk
}; jWUrw
TB>_#+:
typedef union _tagUtype_ zeMV_rW~
{ ?ES{t4"
TestUnion obj; uU)t_W&-J
}UT; ~T@E")uR
k M/:n
int main (void) r ~{nlLO}
{ WfO E I1
return 0; K}cZK
} +PYV-@q
;l;jTb ^l
JYc:@\
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: OAkqPG&w
TIp\-
class TestUnion lz`\Q6rZ
{ ?*~
~Ok
public: s>DFAu!
int data_; z"<S$sDh
}; ]4t1dVD
Sqp91[,
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Jj]<SWh
F7} yt
二、类中union的初始化 D!* SA
46f-po_
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: EZWWvL
(1=@.srAzK
#pragma warning(disable : 4786) Idu'+O4
#include w8+phN(-M
s1OSuSL>
using namespace std; Wgf
f+7k
s3Bo'hGxG
class TestUnion :LuA6
{ @w33u^
enum StoreType{Long,Const_CharP}; t,Tq3zB
union %5L~&W}^"
{ R UCUEo63
const char* ch_; qi@Nz=t#HJ
long l_; &LV'"2ng8
} data_; #: EhGlq8
StoreType stype_; h/5V~ :)
TestUnion(TestUnion&); c
CjN8<
TestUnion& operator=(const TestUnion&); ~p+
`pwjY1
public: *[>{9V
TestUnion(const char* ch); Cno[:iom
TestUnion(long l); `_D A!
operator const char*() const {return data_.ch_;} <OiH%:G/1
operator long() const {return data_.l_;} |s#,^SJ0
}; HZ(giAyjq
di;~$rI!?
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) Eb,M+c?
{ ybf,pDY#f
} [g==#[
5> 81Vhc,
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 6ZjUC1
{ 9n5uO[D
} u$qasII
S!-t{Q+j^
int main (void) mJ8EiRSE
{ :MYLap&L&
TestUnion pszobj("yuankai"); 4tkb7D
q
TestUnion lobj(1234); }w=|"a|,
cout<(pszobj)< cout< U8aNL
sw
return 0; Nn0j}ZI)1
} >z3l@
U+-;(Fh~
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: OHY|< &*
Ga^:y=m
class TestUnion vqF=kB"P
{ =BD|uIR
enum StoreType{Long,Const_CharP}; &i805,lx
union DataUnion //不能匿名 Qp@}v7Due
{ IUWJi\,
DataUnion(const char*); //声明const char*构造函数 )eX{a/Be
DataUnion(long); //声明long构造函数 OgK' ~j
const char* ch_; ocS}4.a@
long l_; \^cXmyQ <%
} data_; Vo%ikR #
StoreType stype_; .5~3D97X&
TestUnion(TestUnion&); v/7^v}[<
TestUnion& operator=(const TestUnion&); Ix@nRc'
public: yJw.z#bB#
TestUnion(const char* ch); A/ Sj>Y1j
TestUnion(long l); zo
]-,u
operator const char*() const {return data_.ch_;} t ,EMyZ
operator long() const {return data_.l_;} ErQGVE;zk
}; *\0h^^|@
:VR%I;g ;
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) 9+Wf*:*EW
{//注意data_(ch),这里直接引用data_ eS%8WmCV9<
} OJFWmZ(X
*mw *z|-^V
TestUnion::TestUnion(long l):data_(l),stype_(Long) _GoFwVO
{//注意data_(l),这里直接引用data_ X4k|k>
} R<r,&X?m
y?iW^>|?L=
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) Q}^qu6
{ dA#'HMh@
} &jrc]
TD/ 4lL~(x
TestUnion::DataUnion::DataUnion(long l):l_(l) xd`\Ai
{ LmKY$~5P
} QNZ#SG8
U*BI/wZ
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!