前言 o5)lTVQ~~
PRcW}"m]Qg
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 h BD .IB
-}Vnr\f
一、在union中存储对象 {3cT\u
|Y?1rLC
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? Ey7SQb
qC]6g
#pragma warning(disable : 4786) ;DbEP. %u$
#include },zP,y:cH
using namespace std; #m[R1G#
] }XsP
class TestUnion 8i"v7}
{ <WhdQKFf-
public: CR3<9=Lv>
TestUnion(long l):data_(l) ErmlM#u
{ %"kF i
}; ~~,] b
int data_; o6L\39v_
}; D>neY9
W
u?A} fH
typedef union _tagUtype_ mX2i^.zH
{ lr[U6CJY
TestUnion obj; `F-<P%k
}UT; p,#t[K
mAO$gHQ
int main (void) &5k$v^W5
{ >G`Uc&=
return 0; CWF(OMA
} rD^ b{]E3
Z',Z7QW7
oihn`DY{
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: kF{'?R5w
G':wJ7[]`
class TestUnion ,6N|?<26O
{ j~DTvWg<Jl
public: o_=t9\:
int data_; i3
?cL4
}; Fl8*dXG&
(.r9bl
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! %0-fn'
haTmfh_|
二、类中union的初始化 ">zK1t5=
s0EF{2<F
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: 8kn> ?
YF)uAJ Ak
#pragma warning(disable : 4786) 47<fg&T
#include )I&,kH)+
R*S9[fqC[
using namespace std; 4\?z^^
(%N=7?
class TestUnion }.ZT?p\
{ C_5o&O8Bc
enum StoreType{Long,Const_CharP}; N+0[p@0
union ([g[\c,H
{ '.{tE*
const char* ch_; d1[;~)
long l_; JCe%;U
} data_; O%Hc%EfG
StoreType stype_; `eo$o!
TestUnion(TestUnion&); :}B=Bk/q
TestUnion& operator=(const TestUnion&); .<fn+]
public: S1vUP5cZ
TestUnion(const char* ch); '}$]V>/
TestUnion(long l); Yo-$Z-ud
operator const char*() const {return data_.ch_;} 4LY$;J;2
operator long() const {return data_.l_;} ZBY*C;[)*P
}; P*
Z1Rs_
" z8iuF
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) FN+x<VXo(
{ hD*83_S
} ByU&fx2Z
@A.7`*i_
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ;#/Uo8
{ k00&+C
} #{8t
?v l
O)FkpZc@9c
int main (void) U,g)N[|
{ IE*5p6IM~
TestUnion pszobj("yuankai"); 0F5QAR
O
TestUnion lobj(1234); J/k4CV*li(
cout<(pszobj)< cout< &Hj1jM'
return 0; HKXtS>7d
} eWk
W,a
%E\ pd@
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 7`P1=`..
BD_"w]bqD
class TestUnion yhsbso,5 a
{ Hw\hTTK
enum StoreType{Long,Const_CharP}; .-mlV ^
union DataUnion //不能匿名 M> rertUR
{ .L=C7 w1
DataUnion(const char*); //声明const char*构造函数 6j6P&[
DataUnion(long); //声明long构造函数 Rq[VP#
const char* ch_; ;\],R.!
long l_; KB`">zq$u
} data_; cs-dvpMZ
StoreType stype_; 3bK=Q3N
TestUnion(TestUnion&); '{F
Od_uk%
TestUnion& operator=(const TestUnion&); &eIwlynm
public: X B[C&3I
TestUnion(const char* ch); # n\|Q\W
TestUnion(long l); q6T>y%|FZ
operator const char*() const {return data_.ch_;} , 9"A"p*R
operator long() const {return data_.l_;} 52v@zDY
}; KrqO7
s g6e%
5
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Dy|DQ> ?}
{//注意data_(ch),这里直接引用data_ Uv|^k8(
} Y{c+/n3d
MngfXm
TestUnion::TestUnion(long l):data_(l),stype_(Long) )#0Llx!
{//注意data_(l),这里直接引用data_ ]D\p<4uepM
} <xaB$}R
'U{6LSaCb
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) yiAusl;
{ QV*W#K\7q
} k}908%w
Y^ti;:
TestUnion::DataUnion::DataUnion(long l):l_(l) 9
:FzSD
{ vy{YGT
} nTH!_S>b(Y
n||!/u)*
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!