前言 gEsD7]o(=
P$Vh{]4i{
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 8tR6.09'
J)B3o$
一、在union中存储对象 rhQ+ylt8I
gh*k\0
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ]gVA6B?&9
B=K<k+{6"
#pragma warning(disable : 4786) -e(<Jd_=
#include -s2)!Iko&
using namespace std; *Vq'%b9
]S s63Vd
class TestUnion g2TK(S|#
{ Uz,P^\8^$
public: Jj[3rt?8
TestUnion(long l):data_(l) Mn/
{ gizY4~
j
}; 1}|y^oB\-
int data_; ,"`3N2!Y}
}; \mGb|aF8
*\xRNgEQ
typedef union _tagUtype_ ]~dB|WB
{ ,&4
[`d
TestUnion obj; 8A]8yX =
}UT; hz;SDaBA
Od;k}u6;<
int main (void) @w= =*.x
{ *(q{k%/M
return 0; 5OGwOZAj52
} hs;|,r
!gRU;ZQU_
0 fT*O
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: X%-hTl
rU"AO}6\@
class TestUnion .O0eSp|e
{ j -o
public: KYB3n85 1
int data_; ,?j!c*
}; k7*-v/*S
.aa7*e
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! DL~!
^fx
0K.$C~C
二、类中union的初始化 "gI-S[
@(a~p
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: E#m^.B-}
YK8l#8K
#pragma warning(disable : 4786) gM1:*YK
#include ~oSA&v4V
CpN*1s})d
using namespace std; XU}i<5
\)\n5F:Zu
class TestUnion F czia0@z
{ %1;Y`>
enum StoreType{Long,Const_CharP}; 8cY5:plK
union 4jZt0
{ jzDPn<WQ
const char* ch_; i`CNgScF>
long l_; N|>MqH,Bt
} data_; E.:eO??g
StoreType stype_; w].DLoz
TestUnion(TestUnion&); x?{l<mc
TestUnion& operator=(const TestUnion&); lxXF8c>U
public: L67yL( d6a
TestUnion(const char* ch); H/x9w[\+[
TestUnion(long l); >/C,1}p[
operator const char*() const {return data_.ch_;} 9} C(M?d
operator long() const {return data_.l_;} L)|hjpQ
}; {yf,:5
<]S
M$)=D
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) T` v
{ hZ<FCY,/?
} "0G)S'
r7U[QTM%
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 8_D:#i
{ ^|rzqXW
} 0""%@X]m
;erxB6*
int main (void) yP@#1KLa+
{ YL;*%XmAG
TestUnion pszobj("yuankai"); }VH`\g}
TestUnion lobj(1234); = "Lb5!
cout<(pszobj)< cout< Jn?ZJZ
return 0; P6^\*xkMr
} ='eQh\T)
wjID*s[
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 9WoTo ,q
J{uqbrJICr
class TestUnion "el3mloR8
{ %kBrxf
enum StoreType{Long,Const_CharP}; +@Kq
union DataUnion //不能匿名 jw2hB[WR
{ >]\oVG
DataUnion(const char*); //声明const char*构造函数 QE;,mC>
DataUnion(long); //声明long构造函数 Tt0]G_
const char* ch_; SV2\vby}C
long l_; ~ebm,3?
} data_; 1RQM-0W,
StoreType stype_; ,8p-EH
TestUnion(TestUnion&); S^e e<%-
TestUnion& operator=(const TestUnion&); [9CBTSr
public: 4%jSqT@
TestUnion(const char* ch); v>Kv!OY:c
TestUnion(long l); ir)~T0
operator const char*() const {return data_.ch_;} Vc|QW
operator long() const {return data_.l_;} Mm"0Ip2"
}; +{e2TY
b Oh[(O!
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) ~|wh/]{b9
{//注意data_(ch),这里直接引用data_ ,}OQzK/"mP
} ",E$}=
,Z
_32 o7}!x
TestUnion::TestUnion(long l):data_(l),stype_(Long) !|
GD8i
{//注意data_(l),这里直接引用data_ 8`w#)6(V
} Kzfy0LWM
UD]RWN
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 8g_GXtn(z
{ pEGHW;
} @2A&eLwLH
ZoKX ao
TestUnion::DataUnion::DataUnion(long l):l_(l) lS`VJA6l.
{ x5W@zqj
} /$ueLa
g>f_'7F&
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!