前言 [^CV>RuO
ca i<,3H
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 o[oM8o<
~5Pb&+<$
一、在union中存储对象 6E(Qx~iL
o#) {1<0vg
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ,}oM-B
qm/Q65>E
#pragma warning(disable : 4786) :NJ_n6E
#include pl@O
N"=[
using namespace std; NBl+_/2'w
)?+$x[f!*
class TestUnion vgY3L
{ Z;9>S=w!
public: ^b: (jI*l
TestUnion(long l):data_(l) .2d9?p3Y
{ :w}{$v}#D;
}; T134ZXqqz
int data_; ojYbR<jn9
}; 'z76Sa
sn7AR88M;
typedef union _tagUtype_ f}g\D#`]/
{ Lg8nj< TF
TestUnion obj; *I}`dC[
}UT;
'iLpE7
4tL<q_
int main (void) ~wg:!VWA)
{ X%yO5c\l2
return 0; ]7-&V-Ct*
} F,
U*yj
@SCI"H%[
J>fQNW!{
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: +"9hWb5
g^*<f8 ~d
class TestUnion ; ^t{Il'j
{ h(WrL
public: dJ$"l|$$
int data_; fXrXV~'8
}; d%l{V6
^u3V
E
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! f0Bto/,>~
LU!dN "[k
二、类中union的初始化 h -iJlm
&-(463
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: 3u%{dG a
z-M3
#pragma warning(disable : 4786) 9x,RvWTb
#include >S$Z
ss;R8:5
using namespace std; 8~5cJPi6
a0r"N[&
class TestUnion l7&$}x-
{ [O:
!(Gje
enum StoreType{Long,Const_CharP}; SG6sw]x
union j*~T1i
{ ySI~{YVM
const char* ch_; 9 \^|6k,
long l_; Mq';S^
} data_; AwQ?l(iZ"p
StoreType stype_; %,+leKs
TestUnion(TestUnion&); bn
|zl!Pq
TestUnion& operator=(const TestUnion&); qI^
/"k*5
public: n3J53| %v
TestUnion(const char* ch); C6rg<tCH
TestUnion(long l); NcY608C
operator const char*() const {return data_.ch_;} B"%{i-v>**
operator long() const {return data_.l_;} AT5aDEb^^
}; 6 uKTGc4
Jx'i2&hGN
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) M'_9A
{ Tw +
} `xrmT t
X
5d Z |!
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 1sYEZO;
{ m3o,@=b
} 42]pYm(jk3
;WldHaZ9r
int main (void) ^MBm==heL
{ =4 h+
M$2
TestUnion pszobj("yuankai"); ~c6}
TestUnion lobj(1234); fGmT_C0t
cout<(pszobj)< cout< SNY~9:;]f
return 0; #s!'+|2n
} ]9\!;Bz^J
P./VmY'
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: {3&|tk!*
QBR=0(giF
class TestUnion Rb\6;i8R
{ WJ*n29^N^h
enum StoreType{Long,Const_CharP}; 5xii(\lC
union DataUnion //不能匿名 A&>.74}p
{ V2N_8)s9W
DataUnion(const char*); //声明const char*构造函数 &w=3^
DataUnion(long); //声明long构造函数 Y#g4$"G9
const char* ch_; p ;|jI1
long l_; < y*x]}
} data_; m*mm\wN5
StoreType stype_; |ae97 5
TestUnion(TestUnion&); S4=R^];l
TestUnion& operator=(const TestUnion&); NKQOUw:qn
public: hR.@b*q?R
TestUnion(const char* ch); L<fvKmo(fw
TestUnion(long l); JgHM?AWg|
operator const char*() const {return data_.ch_;} `U2DkY&n
operator long() const {return data_.l_;} Mg^e3D1_
}; o=nsy]'&
w9|w2UK
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) 5+fLeC;
{//注意data_(ch),这里直接引用data_ 29reG,>
} Q[#vTB$f
7 w3CXY
TestUnion::TestUnion(long l):data_(l),stype_(Long) s@fTj$h
{//注意data_(l),这里直接引用data_ Wa?; ^T
} \Y{k7^G}A
<x!GE>sf+
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) UUMtyf
{ >CkjUZu]&
} J!DF^fLe
DS<}@
TestUnion::DataUnion::DataUnion(long l):l_(l) Ux+Q
{ }W
^: cp
} ~b:Rd{
T6~_Q}6
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!