前言 ges J/I
Yp2e Bgo"
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 >~+ELVB&
*EwR!L*
一、在union中存储对象 K)k<Rh[<
VTHH&$ZNq
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? s=/v';5J2!
|)/aGZ+
#pragma warning(disable : 4786) z,%$+)K
#include 2SR: FUV/
using namespace std; t#eTV@-
!m?-!:
class TestUnion d9|<@A
{ 3|Xyl`i4o
public: "`1bA"E
TestUnion(long l):data_(l) }?v )N).kW
{ Z>#i**
}; 2Q:+_v
int data_; ^&Y#)II
}; fL7xq$K
0% I=d
typedef union _tagUtype_ @>H75
{ D*|Bb?
TestUnion obj; 4x[S\,20
}UT; ayF\nk4b
t}/( b/VD
int main (void) \mlqO[ S
{ 0h7r&t%YsV
return 0; >!)DM]Ri
} Jma1N;d
`%WU8Yv
cD'V>[h
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: fw{gx
fvxu#m=
class TestUnion :tv,]05t
{ >`ZyG5
public: | (_
int data_; 1|-Dj|
}; \=0Vi6!Mc
RhLVg~x
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! 3I-MdApT
q;)JISf.
二、类中union的初始化 rguC p}r
$z*'fXg
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: T 0rGM
h>OfOx/{q9
#pragma warning(disable : 4786) 85xR2 <:
#include f^XOUh
'Ne@e)s9
using namespace std; 1c{DY
aPbE;"
f
class TestUnion Q^txVUL
{ ^eYVWQ'
enum StoreType{Long,Const_CharP}; LTx,cP
union }Y36C.@H
{ [87,s.MK
const char* ch_; !ff&W1@
long l_; $(>+VH`l
} data_; R`^_(yn>
StoreType stype_; hSyql
TestUnion(TestUnion&); N7R!C)!IL
TestUnion& operator=(const TestUnion&); 3"KCh\\b
public: 9j:"J` '
TestUnion(const char* ch); HEc+;O1<
TestUnion(long l); 9o:Lz5o
operator const char*() const {return data_.ch_;} x0w4)Ic5
operator long() const {return data_.l_;} j9+w#G]hV
}; .z}~4BY
K~ehP[^
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) :T
!'N\7
{ L AAHEv
} K1!j fp
ax5<#3__
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ur7q [n
{ G?/DrnK:
} _D(rI#q
2u*KM`fa`
int main (void) yFlm[K5YD
{ 9.B
KI/
TestUnion pszobj("yuankai"); Px`!A EFd[
TestUnion lobj(1234); Q9G;V]./
cout<(pszobj)< cout< ly3\e_z:G
return 0; HcSXsF
} tr}Loq\y
*CTlOy
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: (|1A?@sJ#h
{
W{]L:
class TestUnion 0$fpIz
{ N `F~n%N
enum StoreType{Long,Const_CharP}; 7 X'u6$i
union DataUnion //不能匿名 XaPV94
{ k%QpegN
DataUnion(const char*); //声明const char*构造函数 l u%}h7ng
DataUnion(long); //声明long构造函数 9kS^Abtk
const char* ch_; CDR@
`1-
long l_; h/hmlnOQl
} data_; Cg?&wj<
StoreType stype_; d;9FB[MmOJ
TestUnion(TestUnion&); ls:w8&`*
TestUnion& operator=(const TestUnion&); ~d*(=G
public: p/@smke
TestUnion(const char* ch); o:P}Wg/NK
TestUnion(long l); .rqhi
operator const char*() const {return data_.ch_;} @>>~CZ`l
operator long() const {return data_.l_;} +jnJ|h({
}; JKmIvZ)8
@8rx`9
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) 0-yp,G
{//注意data_(ch),这里直接引用data_ .j<]mUY
} "v({,
~=RT*>G_
TestUnion::TestUnion(long l):data_(l),stype_(Long) KRMQtgahc
{//注意data_(l),这里直接引用data_ OCaq3_#tZ
} x%!s:LVX
f-G:uI_
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) h2J/c#Qvh
{ F Yzi~L
} 3!oi +_
dD|OSB7I7
TestUnion::DataUnion::DataUnion(long l):l_(l) NmJWU:W_@
{ hD*SpVIU
} P?B;_W+~A.
LKOwxF#TKT
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!