前言 j/*4Wj[
3 V{&o,6
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 {((|IvP`
aFtL_#
U
一、在union中存储对象 mCQn '{)
}`*DMI;-
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ("5Eed
9&7$oI$!J
#pragma warning(disable : 4786) [r;hF
#include J sc`^a%`'
using namespace std; v dR6y
'>0rp\jC
class TestUnion V1!;Hvm]+
{ c</u]TD
public: 'X{J~fEI!
TestUnion(long l):data_(l) "j] r
{ O0cKmh6=
}; t)h{ w"v
int data_; 6}S1um4 F
}; +!9&zYu!
jg+q{ ^
typedef union _tagUtype_ }"o,j>IP
{ cBz_L"5vr[
TestUnion obj; UKfpoDhEe
}UT; Bgy?k K2[
,)](h+zl_6
int main (void) 'awZ-$#
{ |JRaskd
return 0; /By`FW Y
} dp'xd>m
+Oa+G.;)o4
NP< {WL#
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: l7M![Ur
[Adkj
class TestUnion QH.zsqf(
{ T3#KuiwU9
public: >wJt# ZB
int data_; (HD=m,}
}; u~VvGLFf5,
c"x-_Uk
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ];VJ54
"Oj2B|:s&
二、类中union的初始化 3El5g0'G
B9(e"cMm
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: .6xIg+
bX*c-r:
#pragma warning(disable : 4786) oA'LQ
#include p?qW;1
H%
"R _[+
using namespace std; m#kJ((~
DS]C`aM9
class TestUnion p@Ng.HE
{ =p29}^@@t
enum StoreType{Long,Const_CharP}; l
S m7i
union 8M9}os
{ $yY\[C
const char* ch_; i$bHet
long l_; +rcDA|
} data_; U~1jmxE
StoreType stype_; 5^ +QTQ
TestUnion(TestUnion&); (iO8[
TestUnion& operator=(const TestUnion&); s_`=ugue
public: k5ZkD+0Jo
TestUnion(const char* ch); sn6:\X<[
TestUnion(long l); A(dWAe,
operator const char*() const {return data_.ch_;} lX*IEAc
operator long() const {return data_.l_;} uBXl ltU
}; pk5W!K
tH\ aHU[
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) ;4]
s P^+
{ k~+(X|!5w
} }'.k
<~}#Q,9
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) nm.~~h+8M
{ h..D1(M
} @%}4R`S0
1deNrmp%
int main (void) 4EtP|
{ K)!Nf.r$9
TestUnion pszobj("yuankai"); %e,X7W`'2
TestUnion lobj(1234); VM [U&g<8n
cout<(pszobj)< cout< Dd:;8Xo
return 0; SC6cFyp2
} FsdxLMwk1
*'&mcEpg
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: Rz_fNlA
JDA :)[;
class TestUnion p[Yja y+
{ Nt^9N
#+N
enum StoreType{Long,Const_CharP}; %:~LU]KX
union DataUnion //不能匿名 ~=xS\@UY =
{ 5\6S5JyIL
DataUnion(const char*); //声明const char*构造函数 Mw,7+
DataUnion(long); //声明long构造函数 `NNr]__
const char* ch_; Mc#w:UH[
long l_; UNB'Xjp}@
} data_; !0+!%Nr>J
StoreType stype_; ;#F7Fp *U
TestUnion(TestUnion&); Ka$YKY,
TestUnion& operator=(const TestUnion&); [EX@I
=?
public: /v^1/i
TestUnion(const char* ch); Aa#WhF
TestUnion(long l); 9Nkr=/I"P
operator const char*() const {return data_.ch_;} ^Cm9[1p
operator long() const {return data_.l_;} 2kS]:4)T
}; 5u=(zg
:UrS@W^B
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) lNw8eT~2
{//注意data_(ch),这里直接引用data_ D:yj#&I
} /y.+N`_
OE4hGxG
TestUnion::TestUnion(long l):data_(l),stype_(Long) SK@%r
{//注意data_(l),这里直接引用data_ 7@@,4_q E
} C~&~Ano,
wgeR%#DW
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) L9Gxqw
{ OE=]/([
} D$wl.r
tAM t7p-
TestUnion::DataUnion::DataUnion(long l):l_(l) ~H)s>6>#v
{ ygA~d9"
} WHM|kt
N7b+GqYpF>
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!