前言 q.u[g0h;
VR5e CJ:i
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 [qjAq@@N#q
B6Wq/fl/
一、在union中存储对象 aHVdClD2o
hPEp0("
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? JsWq._O{/
W>t&N
#pragma warning(disable : 4786) 1DI"LIL
#include R9|2&pfm(M
using namespace std; 3_R
c:`` Y:
class TestUnion B~'VDOG$Z
{ yP1Y3Tga=
public: xqi*N13
TestUnion(long l):data_(l) ]IbPWBX
{ r=iMo7q
}; @?^LxqAWA
int data_; d
=B@EyN
}; J;Z>fAE7
yccuTQvz
typedef union _tagUtype_ Wzf1-0t
{ t^bdi}[
TestUnion obj; S,)|~#5x
}UT; ` + n
mv9E{m
int main (void) 6Mf3)o2
{ fa*H cz
return 0; ,:dEEL+>c
} a2klOX{
qk+{S[2j
?( dYW7S
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: #$vhC u<I
"Wn?8vR
class TestUnion &[2Ej|o
{ x(/@Pt2B
public: \+evZ{Pu
int data_; y}:)cA~o(y
}; EZwdx
5E oWyy
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! HHu7{,
l:5CM[mZ
二、类中union的初始化 9Sj:nn^/u
Uf2v$Jl+Yh
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: Kn!0S<ssR
z
kX-"}$8
#pragma warning(disable : 4786) dbq{a
#include k,*#I<($
#@\NdW\
using namespace std; afP&+ 5t@O
UmD-7Fd
class TestUnion ~&j`9jdOj
{ ?3"D|
cS1
enum StoreType{Long,Const_CharP}; gA6h5F)_
union kvgs $
{ Y+_5"LV
const char* ch_; 7N59B z
long l_; dD.d?rnZq7
} data_; ,b.4uJg'
StoreType stype_; ?od}~G4s#
TestUnion(TestUnion&);
UA!Gr3
TestUnion& operator=(const TestUnion&); ap$tu3j
public: YaJ{"'}
TestUnion(const char* ch); x 1x j\O
TestUnion(long l); i\Q"a B"r
operator const char*() const {return data_.ch_;} c]>&6-;rf
operator long() const {return data_.l_;} &6^W%r
}; :2UC{_
`d|bH;w
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) &fd4IO/O
{ FskJyB[
} 8$<AxNR
MkNURy>n&
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) `F+x]<m!
{ ssJDaf79
} sc $QbO c
#!d^3iB2
int main (void) R$;&O.
5M
{ [ls ?IFg
TestUnion pszobj("yuankai"); xm10
TestUnion lobj(1234); % 6hw
cout<(pszobj)< cout< ,8"[ /@
return 0; C}P
\kDM
} ?'/5%f`
ox=7N{+`J
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: F)5B[.ce
~h^}W$pO
class TestUnion if!`Qid
{ ~j&:)a'^
enum StoreType{Long,Const_CharP}; k-ex<el)#
union DataUnion //不能匿名 7+!7]'V
{ Y\z\{JW
DataUnion(const char*); //声明const char*构造函数 cV_IG}LJ
DataUnion(long); //声明long构造函数 S.F=$z.%
const char* ch_; (jE:Q2"
long l_; wh m tEY
} data_; vsz^B
:j
StoreType stype_; b;{"lJ:+Z
TestUnion(TestUnion&); ?6YUb;
TestUnion& operator=(const TestUnion&); 'iISbOM
public: 6j"I5,-~!
TestUnion(const char* ch); hC,-9c
TestUnion(long l); WKIiJ{@L
operator const char*() const {return data_.ch_;} .SV3<)
operator long() const {return data_.l_;} X@AkA9'fq
}; s^?sJUj
\y )4`A
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) PLD'Q,R
{//注意data_(ch),这里直接引用data_ b}L,kT
} 7CL@iL Tq
g&F<Uv#mZ
TestUnion::TestUnion(long l):data_(l),stype_(Long) A{Htpm ~
{//注意data_(l),这里直接引用data_ )>M@hIV5>
} Y7V&zF{
[`-O-?=
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 8!%"/*P$
{ ~W *j^+T"
} Q.2nUT`
,Ho.O7H
TestUnion::DataUnion::DataUnion(long l):l_(l) I.0P7eA-
{ ;$L!`"jn
} >\.[}th}
jKV?!~/F
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!