前言 iyN:%ofh
AJt+p&I[J
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 Qd)q([
>u>5{4
一、在union中存储对象 RPwbTAl}
D{!6Y*d6&s
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? `CBZhI%%
H[m:0eF'5
#pragma warning(disable : 4786) ~3^
8>d/
#include B`YTl~4
using namespace std; LuNc,n%
_uWpJhCT
class TestUnion ?fiIwF)
{ 7jxslI&F
public: }\hVy(\c
TestUnion(long l):data_(l) )5rb&M}
{ Ut*`:]la
}; 8G9s<N}5&u
int data_; YA''2Ii
}; \?w2a$?6w
%]Fd[pzF
typedef union _tagUtype_ cIUHa
{ &@G:G(
TestUnion obj; P !AEf#1
}UT; B+Rm>^CBm
k\wW##=v
int main (void) b v G/|U
{ oin$-i|Xp!
return 0; ?iPC*
} >x/z7v?^I
gRrL[z
DD7h^-x
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: BYpG
+GG9^:<yr
class TestUnion *Tas`WA
{ 4^:\0UF
public: bmJ5MF]_fG
int data_; ztnFhJ<a$
}; ?b*s.
^
VE#Wb7
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! kEJj=wx
rEv@YD
二、类中union的初始化 VkvB<3
RzxNbeki[W
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: C+'/>=>a.
'r4/e-`pK
#pragma warning(disable : 4786) Mx&&0#;r
#include {,3>"
B&\IGWG(
using namespace std; W6f/T3
AZ0;3<FfLp
class TestUnion H+1-] 'g`
{ ,X#2\r<|
enum StoreType{Long,Const_CharP}; 9G9fDG#F\I
union N8k00*p65
{ 2w59^"<,
const char* ch_; +s(HOq)b
long l_; @AGn{q
} data_; 0F]>Jby
StoreType stype_; ./,/y"x
TestUnion(TestUnion&); b8~Bazk
TestUnion& operator=(const TestUnion&); B$-R-S6
public: V`X2>-Ex
TestUnion(const char* ch); <%($7VMev
TestUnion(long l); JM=JH
51`
operator const char*() const {return data_.ch_;} }#.L7SIJ<J
operator long() const {return data_.l_;} "*m_> IU
}; $8;R[SU6Y
[ad@*KFxy3
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) *-MM<|Qt
{ '{E@*T/<.
} txW{7[w+,
-j%,Oo
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) TFH \K{DM
{ :axRoRg
} a&tSj35*6
+,2:g}5
int main (void) 9
TvV=
{ "^4_@ oo
TestUnion pszobj("yuankai"); k,'L}SK
TestUnion lobj(1234); A9f)tqbc
cout<(pszobj)< cout< .l>77zM6
return 0; f%Ns[S~ r
} M*z~gOZ
/]=C{)8
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: (5#nrF]
>SML"+>
class TestUnion |K6REkzr
{ 9F4Dm*_<
enum StoreType{Long,Const_CharP}; <Fi%iA
union DataUnion //不能匿名 {XNREjhm
{ j/>$,
DataUnion(const char*); //声明const char*构造函数 b?TO=~k,
DataUnion(long); //声明long构造函数 V^JV4 `o
const char* ch_; U'8bdsF_
long l_; lp<g\
} data_; Qj,]N@7
StoreType stype_; *RXbc~
H
TestUnion(TestUnion&); S/^"@?z,vE
TestUnion& operator=(const TestUnion&); VTG9$rQZ
public: &0NFb^8+
TestUnion(const char* ch); k *Q<3@S
TestUnion(long l); 2W/?q!t
operator const char*() const {return data_.ch_;} @\0Eu212
operator long() const {return data_.l_;} CZ(/=3,3n
}; 6,d@p
]3VI|f$$
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) y$@ZN~8
{//注意data_(ch),这里直接引用data_ D[^m{ 9_
} Gs9:6
@c<3b2
TestUnion::TestUnion(long l):data_(l),stype_(Long) R(2tlZ
{//注意data_(l),这里直接引用data_ hJDi7P
} c%&:6QniZ
{P{bOe
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) zY,r9<I8_x
{ T(e!_VY|m
} NbC@z9Q
@r#v[I
TestUnion::DataUnion::DataUnion(long l):l_(l) BB~OqZIP
{ hg+X(0
} QS{1CC9$
bKrhIU[
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!