前言 'b"TH^\
(!?K7<Jv
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 _2vd`k
R,@g7p
一、在union中存储对象 ?HHzQ4w%{
99 wc
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? sNU}n<J-
mE#nU(+Ta
#pragma warning(disable : 4786)
s* jfMY
#include ]qw0V
using namespace std; bZipm(e
")lw9t`
class TestUnion .+K
S`
{ B>TSdn={>
public: D!TZI
TestUnion(long l):data_(l) l*7?Y7FK
{ +'03>!V
}; K6pR8z*?
int data_; D>wZ0p b-
}; %kU'hzLg
XY+y}D
%
typedef union _tagUtype_ `EMi0hm&H
{ *i<\iMoW
TestUnion obj; S-Ai3)t6
}UT; I+,SZ]n
$EBb"+Y'T
int main (void) Jfg7\&|
{ NO>k
return 0; ]7qiUdxt:
} fUcLfnr
.`C
V^\
8V5a%2eV
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: ;6DnId2Zh
xX@FWAj
class TestUnion N?23 m`3
{ -p#,5}
public: z \?UGxu}
int data_; t%+$"nP
}; G?V"SU.
QD<eQsvV
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Q;26V4
:%tuNJjj
二、类中union的初始化 F,v7ifo#f
.RRlUWu
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: [!?wyv3
T{S4|G1R6
#pragma warning(disable : 4786) QB 77:E
#include t =dO
`mB.pz[
using namespace std; 2@MN]Low
mtw9AoO
class TestUnion J_ V,XO
{ zLek&s&-
enum StoreType{Long,Const_CharP}; FDLd&4Ex
union V-vlTgemwc
{ <TjBd1
const char* ch_; zk>h u<_
long l_; |< N frz
} data_; NfF~dK|
StoreType stype_; koH4~m{
TestUnion(TestUnion&); %D^bahf
TestUnion& operator=(const TestUnion&); &`@M8-m#F
public: /4C`k=>
TestUnion(const char* ch); eF1.VLI
TestUnion(long l); yDtOpM8<{
operator const char*() const {return data_.ch_;} J E)J<9gf
operator long() const {return data_.l_;} u7muaSy
}; `-D$Fsl
VG#Q;Xd}
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) V.,bwPb{9
{ K+mU_+KRp
} R`Qpd3
sx-F8:Qa
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) c)3O/`
{ ahp1!=Z-=
} u33zceE8
UB&2f>
int main (void) :QKb#4/8;
{ j)6G7T|
TestUnion pszobj("yuankai"); WEVl9]b'e+
TestUnion lobj(1234); ^K*-G@B
cout<(pszobj)< cout< _$(GRNRYK
return 0; ve%l({
} X>/K/M
L<)Z> @fR
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: r{V.jZ%p'Z
h[H%:743
class TestUnion Ej|A
; &E
{ m0Z7N5v)
enum StoreType{Long,Const_CharP}; 1NGyaI
union DataUnion //不能匿名 ~'[jBn)
{ 3M$X:$b
DataUnion(const char*); //声明const char*构造函数 X2P``YFV{
DataUnion(long); //声明long构造函数 {_as!5l
const char* ch_; b_ JWnh
long l_; I{<;;;a
} data_; F '#^`G9
StoreType stype_; `
@>ZGL:
TestUnion(TestUnion&); qvTJ>FILT
TestUnion& operator=(const TestUnion&); 9}XT'+`y
public: O0zi@2m?B
TestUnion(const char* ch); VIYV92[
TestUnion(long l); wWFW,3b
operator const char*() const {return data_.ch_;} >p |yf.G
operator long() const {return data_.l_;} xSOoIsL[
}; 2H>aC
wfX
H%~Q?4
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) 6JWGu/A
{//注意data_(ch),这里直接引用data_ U6a zhi&,
} !5E9sk{)
.~22^k
TestUnion::TestUnion(long l):data_(l),stype_(Long) 6puVw-X
{//注意data_(l),这里直接引用data_ z'e1"Y.
} O3&|}:<
<O
bH f`Q
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) M1gP
R
{ X{'wWWZC
} &%}6q]e
X?kPi&ru
TestUnion::DataUnion::DataUnion(long l):l_(l) <THUsY`3P&
{ xiJz`KD&
} V^ Y*xZ
xBt<Yt"
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!