前言 A5Y z|
LT#*nr
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 6W#M[0
k((_~<$2K
一、在union中存储对象 v:s~Y
@/B&R^aVZ
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? b.;F)(
ks
3<zW(
#pragma warning(disable : 4786) %3'80u6BCJ
#include e"[o2=v;5
using namespace std; V
mKMj'
n#bC,
class TestUnion TJ2$
Z
{ N[ E
t
public: 80
i<Ij8J
TestUnion(long l):data_(l) ndW??wiM
{ 9M<qk si
}; ]NG`MZ
int data_; W@#)8];>
}; krI<'m;a
l9#M`x9
typedef union _tagUtype_ iHWl%]7sN
{ A;q}SO%b
TestUnion obj; |brl<*:
}UT; tE=P9 \4
rjx6Ad/\
int main (void) 1i#M(u_
{ m7g; psg
return 0; |HhUU1!
} h68sQd
;la(Q~#
G W|~sE +
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: NFU 5+X-c
MXSPD#gN
class TestUnion gKn"e|A
{ "*XR'9~7
public: L%U-MOS=
int data_; "4oY F:h
}; Ej8EQ%P
/wH]OD{
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! iK= {pd
3dQV5E.
二、类中union的初始化 I[@}+p0
N[z7<$$
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: /
~w\Npf0
5e6]v2 k
#pragma warning(disable : 4786) G8Ns?
#include y]+i.8[
u])N^AY"sj
using namespace std; 50uNgLs
Ql3hq.E
class TestUnion ~t.*B& A
{ 8;-a_VjA)
enum StoreType{Long,Const_CharP}; &0*j nb
union x.xfMM2n
{ +8v^J8q0
const char* ch_; ^e8~eL+
long l_; mJ)o-BV
} data_; j%#n}H
StoreType stype_; jf~/x>Q
TestUnion(TestUnion&);
-[" .km
TestUnion& operator=(const TestUnion&); Qpe&_.&RE
public: t'
o:aI
TestUnion(const char* ch); al(t-3`<
TestUnion(long l); E[)`+:G]
operator const char*() const {return data_.ch_;} Z Z\,iT
operator long() const {return data_.l_;} tTX2>8Gmr
}; :,]V 03
g3Xq@RAJ c
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) A8dIL5
{ \%K< S
} #\GWYWkR
a=.A/;|0*
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) GxuFO5wz
{ jyb/aov
} )F8G q,
WIa4!\Ky!
int main (void) \|L ~#{a
{ vxzh|uF
TestUnion pszobj("yuankai"); pGc_Klq
TestUnion lobj(1234); %J5zfNe)&
cout<(pszobj)< cout< >RG
}u
return 0; 4ac2^`
} z
v*hA/
J/:9;{R
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: Pa'g=-
K|[[A)tt6
class TestUnion "\Zsr6y
{ 4nN%5c~=
enum StoreType{Long,Const_CharP}; 9r+]V=
union DataUnion //不能匿名 PxhB=i!'$
{ 1(CpTaa
DataUnion(const char*); //声明const char*构造函数 WV]Si2pOZ
DataUnion(long); //声明long构造函数 <7~HG(ks
const char* ch_; U,_uy@fE=?
long l_; d OQU#5
} data_; U7bbJ>U_|
StoreType stype_; f R$E*Jd
TestUnion(TestUnion&); /. k4Y
TestUnion& operator=(const TestUnion&); iSCv/Gb:,
public: }te\)
Yk.N
TestUnion(const char* ch); Uf}s6#
TestUnion(long l); F.<sKQ&A
operator const char*() const {return data_.ch_;} l{[{pAm
operator long() const {return data_.l_;} R4.$9_ui
}; OlL
FuVR
,B_Nz}\8
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) "g;^R/sfq
{//注意data_(ch),这里直接引用data_ b) "bX}
} t:B~P,r
s.d }*H-o
TestUnion::TestUnion(long l):data_(l),stype_(Long) d~M;@<eD
{//注意data_(l),这里直接引用data_ M0YV Qa
} 4D=p#KZ
F'^6ra9
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) ;7Cb!v1
{ [xe(FFl+
} se(ZiyHp
P~HzNC
TestUnion::DataUnion::DataUnion(long l):l_(l) Q(=} PF
{ .Zv@iL5
} `dO)}}| y
Xxhzzm-B
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!