前言 KP`{ UD)
@iWql*K;m
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 {hr>m,O%
X-%XZDB6
一、在union中存储对象 pJ!:mt
r)UtS4 7
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? _yw]Cacr\
Ea#wtow|-
#pragma warning(disable : 4786) atRWKsY<
#include 2{:bv~*I0F
using namespace std; H g(%gT
%;$zR}
class TestUnion s4uZ;
{ `1aEV#;
public: s{\USD6
TestUnion(long l):data_(l) lArYlR}
{ eT* )r~
}; @}k5rcQ*/
int data_; H/n3il_-I
}; &~Qi+b0!
VX0q!Q
typedef union _tagUtype_ ^EY^.?Mg
{ p2s*'dab7
TestUnion obj; SC/|o
}UT; @(Q'J`
;K]6/Wt
int main (void) |zhVl
{ b3]QH
h/
return 0; 8L]em&871
} ]w ^9qS
8D7=]
',`GdfAsH
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: Y~@@{zP
EF1aw2
class TestUnion -wJ/j~+m+
{ OE_;i}58
public: |t](4
int data_; /sVy"48-
}; !jZXh1g%
B=?4; l7
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! $*a'[Qot#
80=6B
二、类中union的初始化 7` AQn],
}Fy~DsQ
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: |]FJfMX
X.TsOoy
#pragma warning(disable : 4786) N0TEVDsk
#include 9,8}4Y=GVI
92zo+bc
using namespace std; $}kT)+K
=To}yJ#
class TestUnion 0G@sj7)]
{ X633.]+
enum StoreType{Long,Const_CharP}; !##OQ
union x`:zC#
{ G1K72M}CW
const char* ch_; :2^j/
long l_; o ;nw;]oR
} data_; <Sw>5M!j
StoreType stype_; DLMM1
A
TestUnion(TestUnion&); ?U3X,uv5J
TestUnion& operator=(const TestUnion&); ["]r=l
public: ?}<4LK]
TestUnion(const char* ch); ipy1tXc
TestUnion(long l); l!UF`C0g
operator const char*() const {return data_.ch_;} \Nd8,hE
operator long() const {return data_.l_;} hbfTv;=z
}; N0`v;4gF$]
Z1u:OI@(
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) h,QC#Ak o
{ 0Bbno9Yp
} 6%N.'wf
.C$4jR.KC
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) <*O~?=6p
{ lI#Ap2@
} iBlZw%zKP
u17e
int main (void) zW[fHa$m
{ Z*,Nt6;e
TestUnion pszobj("yuankai"); mWhQds6
TestUnion lobj(1234); ;Oh abbj*
cout<(pszobj)< cout< jpg$5jZ
return 0; sJA` A
} Qe8F(k~k
)8ub1,C
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: g~,"C8-H
jN.'%5Q?H
class TestUnion 4@|"1D3
{ yCk9Xc
enum StoreType{Long,Const_CharP}; >;|~
z\8
union DataUnion //不能匿名 A}K2"lQ#>,
{ 9WE_9$<V
DataUnion(const char*); //声明const char*构造函数 kTJz .
DataUnion(long); //声明long构造函数 A^\A^$|O6
const char* ch_; Ns3k(j16
long l_; ,LD[R1TU8
} data_; 7;]n+QRfm
StoreType stype_; i{1SUx+Re
TestUnion(TestUnion&); T&@xgj|!)
TestUnion& operator=(const TestUnion&); 3RSiu}
public: d5aG6/
TestUnion(const char* ch); ){'Ef_/R
TestUnion(long l); Z1@E
operator const char*() const {return data_.ch_;} 0M[O(.x
operator long() const {return data_.l_;} POZ5W)F(
}; W ='c+3O6
}r%Si
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) vR;?~^{*s
{//注意data_(ch),这里直接引用data_ ,_ zivUU
} g>g]qQ
7t8[M(
TestUnion::TestUnion(long l):data_(l),stype_(Long) AHg:`Wjv-
{//注意data_(l),这里直接引用data_ '!$g<= @
} mPhrMcL
Ab|
tE5%
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) bf#@YkE
{ q#}#A@Rg
} {\HEUIa]w
?\_\pa/+
TestUnion::DataUnion::DataUnion(long l):l_(l) }cl~Vo-mp
{ EMe3Xb
`
} . \/jy]Y
s"tyCDc.c
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!