前言 au1(.(
6cOm 8#
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 yX8$LOjE
5SY( :!
一、在union中存储对象 VJ(#FA2
w+owx(mN@
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? =:=uV0jX\
Ih0kdi
#pragma warning(disable : 4786) bjJ212J
#include $'VFb=?XrK
using namespace std; wg,w;Gle
Q|o~\h<
class TestUnion wN! 5[N"
{ !n/"39KT
public: S-6%mYf
TestUnion(long l):data_(l) S(*SUH
{ )b AcU
}; co%ttH\ n
int data_; 7l3sd5
}; f?A*g$v
i/UHDqZ
typedef union _tagUtype_ i~6qOlLD-
{ &<sDbNS
TestUnion obj; j!P]xl0vOZ
}UT; J;g+
tcf>9YsOr
int main (void) t|aBe7t7
{ <Cw)S8t
return 0; 4HK#]M>yz
} !8O*)=RA
+H~})PeQ
3Ga!)
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: y\&`A:^[ A
9q-9UC!g
class TestUnion +
>oA@z
{ 7,2bR
public: 0xM\+R~,
int data_; 0"L_0 t:
}; 50.cMms
>h7qI-
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! 2 -uL
Z;QbqMj
二、类中union的初始化 X)|b_ 3Z
um[nz
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: +mN]VO*y
-P<e-V%<
#pragma warning(disable : 4786) PSQ5/l?\>
#include TnqspS2;R
Hinz6k6!
using namespace std; viT/$7`AI
8I'c83w
class TestUnion <OcD [5
{ S]3t{s#JW7
enum StoreType{Long,Const_CharP}; y#Ao6Od6
union ^U.8grA
{ Y\len
const char* ch_; bCF"4KXK
long l_; n%]1p36
} data_; #xS8
StoreType stype_; )q\|f_
TestUnion(TestUnion&); TC4W7}}
TestUnion& operator=(const TestUnion&); Ii/#cdgF
public: g,!6,v@
TestUnion(const char* ch); 1#9 Q1@'OS
TestUnion(long l); N4Z%8:"pj
operator const char*() const {return data_.ch_;} spV/+jy{
operator long() const {return data_.l_;} 9BPucXK
}; #AzZ4<;7
;k<g#She
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) "3A.x1uQ
{ DDT)l+: XP
} D0D0=s
%11&8Fp1s
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) MkG3TODfHB
{ X9#;quco@
} AAE8j.
r(IQ)\GR
int main (void) 'dp3>4
{ Q&;dXE h
TestUnion pszobj("yuankai"); POQRq%w
TestUnion lobj(1234); wvum7K{tI
cout<(pszobj)< cout< c@%:aiEl
return 0; X/fk&Cp
} y8uB>z+#+;
t/\J
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: ++Qg5FukR
Cyg\FHs
class TestUnion @54D<Lj
{ MMglo3
enum StoreType{Long,Const_CharP}; jiMI&cl
union DataUnion //不能匿名 ^ 9
gFW $]
{ *4;MO2g
DataUnion(const char*); //声明const char*构造函数 VQO6!ToKY
DataUnion(long); //声明long构造函数 iw <2|]>l
const char* ch_; PK@hf[YHe
long l_; B(x i
} data_; UW*[)y w]
StoreType stype_; /ov&h;
TestUnion(TestUnion&); FV>LD% uu
TestUnion& operator=(const TestUnion&); )pV5l|`
public: "If]qX(w
TestUnion(const char* ch); gN|[n.W4
TestUnion(long l); A"8`5qa
operator const char*() const {return data_.ch_;} ,c#=qb8""
operator long() const {return data_.l_;} uI^E9r/hB
}; ;H5PiSq;z
qh!2dj
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Np=IZnpt
{//注意data_(ch),这里直接引用data_ mdW8RsR
} 6C>"H
5"=qVmT)
TestUnion::TestUnion(long l):data_(l),stype_(Long) Z> jk\[
{//注意data_(l),这里直接引用data_ %Ji@\|Zkf
} 8|uFW7Q
^T83E}
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) vq|o}6Et
{ T> cvV
} ^fT|Wm<
&o>ctf.x
TestUnion::DataUnion::DataUnion(long l):l_(l) *Y'@|xf*
{ JyY-@GF
} Mvq5s +.
M}E0Msq_o
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!