前言 ,[Z;"wE
cNqw(\rr
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 i'vjvc~
q]t^6m&-
一、在union中存储对象 !GVxQll[f
1Aa=&B2
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? Yy0m &3[
<8/lHQ^\)
#pragma warning(disable : 4786) w+tO@
#include H=9\B}
using namespace std; %bUpVyi!(
ZsYT&P2
class TestUnion Tk4"qGC.
{ [p_C?hHO
public: =p';y&
TestUnion(long l):data_(l) rhvsd2zi
{ N
DV_/BI
}; S>p>$m,
Q
int data_; DnPV
Tp(>
}; uc;QSVWGy8
9Uh nr]J.
typedef union _tagUtype_ tt>=Vt'
{ h9J
TestUnion obj; _26F[R1><~
}UT; ktKT=(F&
hC= ="4 -
int main (void) qT L@N9
{ GQ9g $&T
return 0; D<cHa |
} V]9?9-r
3bPvL/\Lb
~UJ_Rr54
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: KcjP39@I
I*K~GXWs#
class TestUnion yS-owtVCGF
{ `_v|O{DC{
public: 1%6}m`3
int data_; VN8ao0^d;d
}; mWM!6"
ZK]C!8\2|
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! |bz,cvlP
W
+P <Lo I
二、类中union的初始化 +<H)DPG<
-.E<~(fad
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: hw&R.F
]Z\.Vx
#pragma warning(disable : 4786) R#Bdfmldq
#include z7J2O
u-. _;
using namespace std; )/9/p17:xu
X;0DQnAI8j
class TestUnion ~(`iR xK
{ kSw.Q2ao
enum StoreType{Long,Const_CharP}; Rj=xn(@d
union qzqv-{.h
{ &u_f:Pog
const char* ch_; K(HP PM\
long l_; ,tL<?6_
} data_; qyuU
StoreType stype_; `=Hh5;ep
TestUnion(TestUnion&); 5A6d]
TestUnion& operator=(const TestUnion&); >2~q{e
public: 6l>$N?a
TestUnion(const char* ch); ^1S(6'a#
TestUnion(long l); LdAfY0
operator const char*() const {return data_.ch_;} "tbKKh66
operator long() const {return data_.l_;} S:Ne g!`
}; 9Qb_BNUo
kGMI
?
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) ;Z"6ve4
{ ALiXT8q
} yA!#>u%g
gX34'<Z
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) Kuy,qZv!"
{ kfBVF%90
} _}7N,Cx
oxb#{o9G
int main (void) W9?Vh{w
{ kQ~*iY
TestUnion pszobj("yuankai"); n8[
sl]L
TestUnion lobj(1234); ;K0kQ<y-Y
cout<(pszobj)< cout< 0zaE?dA]
return 0; b$+.}&M
} : \w\K:
]v3 9ag_hu
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: c?CjJ}-7
ayuj)]b
class TestUnion a="Z]JGk
{ m6)8L?B
enum StoreType{Long,Const_CharP}; 1_!*R]a q
union DataUnion //不能匿名 E[>4b7{g:
{ /v
E >*x
DataUnion(const char*); //声明const char*构造函数 :grJ}i-D
DataUnion(long); //声明long构造函数 auqM>yx
const char* ch_;
'@9h@,tc
long l_; "8aw=3A
} data_; ` ej
StoreType stype_; PWOV~`^;
TestUnion(TestUnion&); b,8W
|
TestUnion& operator=(const TestUnion&); H~1*`m
public: impzqQlZ,
TestUnion(const char* ch); 67Z|=B!7
TestUnion(long l); e;R5A6|
operator const char*() const {return data_.ch_;} O2?ye 4uq
operator long() const {return data_.l_;} PBb@J'b
}; HiEXw}Hkz
RX%*:lXi_
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) xjiMM>|n
{//注意data_(ch),这里直接引用data_ k`6T% [D]
} Sb+pB58&N
;=Jj{FoG%
TestUnion::TestUnion(long l):data_(l),stype_(Long) 2P~zYdjS
{//注意data_(l),这里直接引用data_ iTi<X|X
} =9GL;z:R+
|_8-3
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) a1]k(AuQrC
{ &96I4su
} @kn0f`
7\'vSHIL
TestUnion::DataUnion::DataUnion(long l):l_(l) /pZLt)=P
{ F`3c uL[N
} .{LFc|Z[
)V%xbDd S
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!