前言 )/4U]c{-
I>%@[h,+
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 |emZZj
~/1eF7
一、在union中存储对象 Fa9gr/.F,@
|<w
Z;d
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 4<l&cP
p WLFJH}N
#pragma warning(disable : 4786) .J.|
S4D
#include Y]9C 8c)
using namespace std; &46Ro|XE`
PtT$#>hx]
class TestUnion p<AzpkU,A
{ Vv~:^6il
public: kz?m `~1
TestUnion(long l):data_(l) FX:'38-fk
{ X.hVMX2B
}; YMIX|bj6Y
int data_; 2[TssJQ
}; :P:OQ[$
mIkc+X
typedef union _tagUtype_ vGI?X#w3
{
D?@e,e
TestUnion obj; @g==U{k;t
}UT; 7 J+cs^2
2` j#eB1
int main (void) s5D<c'-
{ 2kQa3Pan
return 0; 8[mj*^P
} z! /
MBM
A Z& ]@Ao
5Q.z#]Lg
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: K!onV3mR
h;`]rK;g
class TestUnion ZX03FJL7u
{ }5a$Ka-
public: 6/&aBE=
int data_; `6`oLu\l
}; >2@ a\
KvfZj
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! /%5X:*:H
IiRII)
二、类中union的初始化 {wyf>L0j
8
!+eq5S3
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: oCR-KR>{Q
Sn~|<Vf
#pragma warning(disable : 4786) PXJ`<XM
#include +oe%bk|A
84UI)nE:Q
using namespace std; ?~s2 3%E
*d;D~"E<@
class TestUnion }~3 %KHT
{ R8YA"(j!L
enum StoreType{Long,Const_CharP}; h!UB#-
union /ng+IC3
{ Q^z&;%q1
const char* ch_; "8YXFg
long l_; ]eD5It\
} data_; L#X!.
StoreType stype_; V=DT.u
TestUnion(TestUnion&); )3RbD#?
TestUnion& operator=(const TestUnion&); zMW[Xx!
public: L fx$M
TestUnion(const char* ch); K3($,aB}
TestUnion(long l); )Y:9sd8g7
operator const char*() const {return data_.ch_;} r%^J3
operator long() const {return data_.l_;} @[(<oX%
}; "f-z3kL
2h^9lrQcQG
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) H&3i[D!p
{ {9yW8&m
} Z2wgfP`
A3=$I&!%
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 35X4]
t
{ >7^i>si
} |)\{Rufb
4_B1qN
int main (void) BO3%p
{ KW5u.phv
TestUnion pszobj("yuankai"); L4C_qb k;:
TestUnion lobj(1234); :w5p#+/,P
cout<(pszobj)< cout< e-.s63hm
return 0; "G,$Sqi@
} MEZc/Ru-[
=9@t6
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: hJcN*2\:
x&PVsXdt5m
class TestUnion ,@*Srrw
{ e$+/;MRq
enum StoreType{Long,Const_CharP}; qqR8E&Y{
union DataUnion //不能匿名 fR6.:7&
{ %juR6zB%8
DataUnion(const char*); //声明const char*构造函数 F4%vEn\!
DataUnion(long); //声明long构造函数 5v@-.p
const char* ch_; ywS2`(
long l_; qq1@v0
} data_; Z}*{4V`R
StoreType stype_; 1__Mf.A
TestUnion(TestUnion&); %x G3z7;
TestUnion& operator=(const TestUnion&); y@?t[A#v
public: "/MA.zEl0,
TestUnion(const char* ch); j/<z[qr
TestUnion(long l); PWw2;3`-6w
operator const char*() const {return data_.ch_;} /5Zt4&r
operator long() const {return data_.l_;} MU/3**zoW
}; |-SImxV
CYCG5)<9
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) L[s8`0
{//注意data_(ch),这里直接引用data_ KnjowK
} 4v("qNw#
"\l O1D
TestUnion::TestUnion(long l):data_(l),stype_(Long) c7fQ{"f 3B
{//注意data_(l),这里直接引用data_ <.lT.>'?
} PF4"J^V
*tD`X(K
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) Qso"jYl<
{ hn@T ]k
} D^~G(m;-
yd-Kg zm8n
TestUnion::DataUnion::DataUnion(long l):l_(l) 1VD8y_tC
{ a7Fc"s*
} !u;r<:g!
NLLLt
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!