前言 "h #/b}/
%%/8B
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 -Lq2K3JHyn
&CcW(-
一、在union中存储对象 LuHRB}W
a]Pw:lT
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? Faa>bc~E
0w:
3/WO
#pragma warning(disable : 4786) OR*JWW[]
#include qpMcVJL
using namespace std; 4lWqQVx
[& Z-
*a
class TestUnion PO8Z2"WI
{ -EE'xh-zD
public: E#_2t)20
TestUnion(long l):data_(l) 4'=Q:o*w`
{ ?wv^X`Q*~
}; 6%h%h: e
int data_; nu7 R
}; y631;dU
E
N%{ $
typedef union _tagUtype_ ErJ/h?+
{ p"c6d'qe
TestUnion obj; h=,hYz?]
}UT; [qW%H,_
BC/5 bA
int main (void) 6r`N\ :18
{ &6C]|13;
return 0; ]hS<"=oj
} K!Fem6R
< K!r\^
e"wzb< b
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: YPGzI]\
MH#"dGGu
class TestUnion pi~5}bF!a
{ R6BbkYWrX
public: dQ7iieT
int data_; ~] V62^0
}; ]7cciob
Wz=&
0>Mm_
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! LdH1sHy*d`
\1gAWUt('
二、类中union的初始化 m3Wc};yE*Q
>J3mta3
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: p0 X%^A,4
y>x"/jzF#
#pragma warning(disable : 4786) ?wPTe^Qtv
#include p\6}<b"p
]T'8O`
using namespace std; yQUrHxm
kJJiDDL0;*
class TestUnion L=qhb;[L
{ AV2Jl"1)z
enum StoreType{Long,Const_CharP}; |Vqm1.1/Zv
union $3l#eKZA
{ 7Z`4Kdh .
const char* ch_; ~`&4?c3p
long l_; P$Vh{]4i{
} data_; >QvqH 2
StoreType stype_; 8 <;.[l
TestUnion(TestUnion&); ]:D&kTc
TestUnion& operator=(const TestUnion&); C(v'7H{4cW
public: _g/d/{-{Q
TestUnion(const char* ch); Yb5@W/'
TestUnion(long l); KTT!P 4
operator const char*() const {return data_.ch_;} nw--
operator long() const {return data_.l_;} [&*irk
}; TM{m:I:Z*n
{$[0YRNk
u
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) 4y+hr
{ (*\&xRY|C
} Lf^
7|
r+[g.`
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) *!y04'p`<
{ uKXU.u*C
} *vRHF1)L
nRqP_*]
int main (void) =/|GWQj
{ O}cfb4"
TestUnion pszobj("yuankai"); uGXvP(Pg'
TestUnion lobj(1234); 2i!R>`
cout<(pszobj)< cout< 3=ME$%f
return 0; |>U<EtA"
} ?:60lCqj
V?JmIor
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: [7DU0Xg7
b_{+O qI
class TestUnion CpN*1s})d
{ g=4P-i3
enum StoreType{Long,Const_CharP}; E5P.x^
union DataUnion //不能匿名 8b,Z)"(U3
{ aMydeTCHi
DataUnion(const char*); //声明const char*构造函数 qfFa" a
DataUnion(long); //声明long构造函数 ;_<
Yzl
const char* ch_; !$iwU3~<
long l_; cqh1,h$sG
} data_; U/q"F<?.c
StoreType stype_; SP2";,%/9
TestUnion(TestUnion&);
2i6P<&@
TestUnion& operator=(const TestUnion&); )06. dZq\
public: hZ<FCY,/?
TestUnion(const char* ch); 2g)q
(
TestUnion(long l); ,bzgjw+R5
operator const char*() const {return data_.ch_;} js)E:+{A,
operator long() const {return data_.l_;} UeBSt.
}; 96F+I!qC
|1OF!(:
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) dXt@x8E
{//注意data_(ch),这里直接引用data_ t2.]v><