前言
+`-a*U94
"M^W:4_
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 u(702S4
zi
.,?Q
一、在union中存储对象 6a?p?I K^
p)xI5,b$9
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? (}1f]$V
"|`9{/]
#pragma warning(disable : 4786) X:&p9_O@
#include mcr#Ze
using namespace std; y#;VGf6lj
+Q31K7G r
class TestUnion 4&hqeY3
{ a<TL&
public: 389.&`Q%Ut
TestUnion(long l):data_(l) K"j=_%{
{ sA-W^*+
}; } <4[(N
int data_; _PUm
Pom.
}; 1Z8Oh_DC
O&iYGREO
typedef union _tagUtype_ FNCLGAiZ
{ )+4}Ix/q
TestUnion obj; ,9wenr
}UT; % 3-\3qx*
Ej09RO"pB
int main (void) ^@L
l(?
{ IPi<sE
return 0; _ZM9
"<M-X
} Cmx2/N
PJ'lZu8?x
2$zq (
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: a {$k<@Ww
ivz9R'
class TestUnion &Z;8J @
{ 1 lCikS^c
public: I=
h4s(
int data_; 4O_+4yS
}; o / g+Z
6Y_O^f
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! <C"N X
j /dE6d
二、类中union的初始化 d3=6MX[c
<ivqe"m
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: pebx#}]p-
C:GHP$/}
#pragma warning(disable : 4786) ?~JxO/K
#include tZu*Asx7
kH8$nk eev
using namespace std; @S"pJeP/f
'Rkvsch
class TestUnion Z:lB:U'o
{ 5Jhbf2-
enum StoreType{Long,Const_CharP}; YUVc9PV)Ws
union N~S[xS?
{ Fwx~ ~"I
const char* ch_; Dj
]Hgg
long l_; (o6[4( G
} data_; g"!#]LLe
StoreType stype_; ELrZ8&5G
TestUnion(TestUnion&); Ld}(*-1i
TestUnion& operator=(const TestUnion&); n:*_uc^C
public: XAU_SPAjiw
TestUnion(const char* ch); aFr!PQp4{
TestUnion(long l); %%+mWz a
operator const char*() const {return data_.ch_;} @W1WReK]f
operator long() const {return data_.l_;} "wF
?Hamz
}; Ck3QrfM
s
la*3~?*
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) .YjrV+om1
{ 9QOr,~~s
} bQXc IIa{
l~fh_IV1
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 8!uL-_ Bn
{ z{`6#
} 3b|7[7}&
Q3BLL`W~
int main (void) 4/HY[FT
{ Hb
A3*2
TestUnion pszobj("yuankai"); C7b
5%a!
TestUnion lobj(1234); -}_cO|kk
cout<(pszobj)< cout< q ab)
1ft
return 0; =`]|/<=9'U
} '0R/6Z|/Y
Th7wP:iDP
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: <TLGfA1bC
:kME
class TestUnion /FP ~jV!z
{ 8/Et&TJ`
enum StoreType{Long,Const_CharP}; ?JXBWB4
union DataUnion //不能匿名
rV8(ia
{ *Nvy+V
DataUnion(const char*); //声明const char*构造函数 qa
6=W
DataUnion(long); //声明long构造函数 j<l#qho{h
const char* ch_; ;f".'9 l^
long l_; "xD}6(NL(r
} data_; ERp:EZ'
StoreType stype_; wUru1_zjO
TestUnion(TestUnion&); pG,<_N@P
TestUnion& operator=(const TestUnion&); tk`: CT
*
public: y\F`B0#$
TestUnion(const char* ch); :k WZSN8.D
TestUnion(long l); X+`ddX
operator const char*() const {return data_.ch_;} f![xn2T
operator long() const {return data_.l_;} SW,q}-
}; n!UMU ^
,pDp>-vI%
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) %$/=4f.j
{//注意data_(ch),这里直接引用data_ -/M9 vS
} }7iUagN
nnfY$&3A
TestUnion::TestUnion(long l):data_(l),stype_(Long) @
\!KF*v
{//注意data_(l),这里直接引用data_ NlA*\vco
} rumAo'T/%
gb]hOB7g
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) .>k=A|3G
{ *w=z~Jq^R"
} AiY|O S3R
@b]VCv0*f%
TestUnion::DataUnion::DataUnion(long l):l_(l) G{F6
{ ])N|[ |$
} ?$<SCN=
9TqnzD
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!