前言 hqW),^\>'
"sU jJ|
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 RA$%3L[A!
c2RQwtN|
一、在union中存储对象 @j`gxM_-O
dI?x(vw
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? =3dR-3
*w`_(Xf
#pragma warning(disable : 4786) s|[CvjL#0
#include w\zNn4B})A
using namespace std; *w
OU=1+
I
R|[&} z
class TestUnion HPc~wX
{ yBl9 a-2A
public: |r+w(TG
TestUnion(long l):data_(l) `Iqh\oY8-
{ s`2q(`}
}; \#sdN#e;XA
int data_; bamQ]>0|>!
}; _zK
~9/5
Mc9J Fzp
typedef union _tagUtype_ 1'YUK"i
{ ?ocBRla
TestUnion obj; QX+Xi<YE-
}UT; c\le8C3
i?:#lbw_
int main (void) @:Emmzucv|
{ t\XA
JU
return 0; dJF3]h Y
}
1}Th@Vq
QJF_ "
"DC L
Z
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: g-4j1yJV<
JI[{n~bhGD
class TestUnion z)ndj
1,#)
{ Sfa;;7W@R
public: p|>m 2(|
int data_; ;Sl%I+?
}; KsSIX
-nQ(.#-n
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! x8o/m$[,=u
?3y>K!D(A
二、类中union的初始化 ]NyN@9u@(
Ke^9R-jP
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: #+ Y%Bxf
Jbn^G7vH<6
#pragma warning(disable : 4786) &Lbh?C
#include *|as-!${k
<8ih >s(C
using namespace std; U'LPaf$O
kD
me>E=
class TestUnion t\WU}aKML
{ ~~3*o
enum StoreType{Long,Const_CharP}; :(YFIW`59
union tTbfyI
{ UCo`l~K)qg
const char* ch_; Z]XjN@j"
long l_; ~7wLnB
} data_; wlFK#iK
StoreType stype_; :;jRAjq"
TestUnion(TestUnion&); i8A-h6E
TestUnion& operator=(const TestUnion&); ;]l`Q,*OXb
public: "^oU&]KQJ
TestUnion(const char* ch); cI'su?
TestUnion(long l); +y^'\KN
operator const char*() const {return data_.ch_;} #x6EZnG
operator long() const {return data_.l_;} ct@3]
}; XzBlT( `w
aZ8f>t1Q
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) E(_lm&,4+
{ 84<zTmm
} aA]wFZ
?_d3|]N
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) hd W7Qck "
{ 6a704l%#hb
} E
BSjU8
nG%<n
int main (void) )4RSo&9p`
{ p2
!w86 F
TestUnion pszobj("yuankai"); >*EJ6FPO
TestUnion lobj(1234); $ I
J^
cout<(pszobj)< cout< j8+>E?nm
return 0; deEc;IAo
} b!qlucAeE
6OR) 97
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: A{Qo}F<*
a-lF}P\
class TestUnion kDG?/j90D
{ /!sGO:
enum StoreType{Long,Const_CharP}; OBf$Z"i
union DataUnion //不能匿名 X/Ii}X/p
{ qIxe)+.
DataUnion(const char*); //声明const char*构造函数 .O SQ8W}
DataUnion(long); //声明long构造函数 o$ #q/L
const char* ch_; t$b5,"G1
long l_; <Y"HCa{
} data_; Z>~7|vl
StoreType stype_; :1;"{=Yx}
TestUnion(TestUnion&); 6]mAtA`Y
TestUnion& operator=(const TestUnion&); Q$Rp?o&
public: :o:Z
TestUnion(const char* ch); p*l=rni4
TestUnion(long l); S{Zf}8?6$
operator const char*() const {return data_.ch_;} iI3,q-LA
operator long() const {return data_.l_;} Z`#XB2,
}; <B'PB"R3y
+UiJWO
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) 8\G"I
{//注意data_(ch),这里直接引用data_ U,lO{J[T
} +1r><do;
TAq[g|N-;
TestUnion::TestUnion(long l):data_(l),stype_(Long) g>g*1oS
{//注意data_(l),这里直接引用data_ )2
b-3lz
} So=
B cX-
vGOO"r(xL
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) X<H{
{ DT_%Rz~<
} @ +a}O
-;Te+E_
TestUnion::DataUnion::DataUnion(long l):l_(l) [
~kS)
{ 6Ilj7m*
} 4wWfaL5"
u4'B
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!