前言 ENF@6]
Q
X5#$-H@
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 HC, 0"W
*[/Xhx"
一、在union中存储对象 ?ut juMdl
.&!{8jBX
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 38S&7>0@|q
6L% R@r
#pragma warning(disable : 4786) S{|)9EKw
#include -`1L[-<d=/
using namespace std; BGYm]b\j[
K`83C`w.
class TestUnion P\4o4MF@K
{ TVh7h`Eg
public: :s985sEv
TestUnion(long l):data_(l) [
:(M<u`y>
{ F[giq1#
}; D`@U[ `Sw
int data_; g<5Pc,
}; [ESs?v$
?'_7#0R_0
typedef union _tagUtype_ dM$G)9N)K
{ /XK`v=~(l{
TestUnion obj; w!k4&Rb3
}UT; J0z0%p
">^]^wa08
int main (void) >~8Df61o`
{ 2gI_*fG1
return 0; C+IE<=%F
} cr;`0
:iC\#i]6
VNot4 62L
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: 1:Gd{z
5"]2@@b4
class TestUnion +>%+r
{ )Ea_:C'
public: Xr;noV-X
int data_; W3j|%
}; l[0P*(I,
6spk* 8e
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! u(a&x|WY
6?x{-Zj^?
二、类中union的初始化 vrDRSc6_
1! [bu
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: oeKc-[r
D6:J*F&?
#pragma warning(disable : 4786) 2^lT!X@
#include ?pY!sG
==r|]~x
using namespace std; U2?gODh'
VO6y9X"
class TestUnion /pN2Jst
{ Wm&f+{LO+K
enum StoreType{Long,Const_CharP}; + # >%bq x
union AWNd(B2o
{ G{Q'N04RA
const char* ch_; <LZvh8
long l_; mR@Xt#
} data_; n?tAa|_
StoreType stype_; Y% 9F
TestUnion(TestUnion&); rq?x]`u
TestUnion& operator=(const TestUnion&); Kn\(Xd.>
public: za/#R_%p
TestUnion(const char* ch); B)`X7uG
TestUnion(long l); rl7Y=*Dv
operator const char*() const {return data_.ch_;} ]vFmY
operator long() const {return data_.l_;} }w8AnaC
}; aH"c0A
?d)|vX3Uf
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) EKD>c$T^
{ ?8m/]P/~
} 6p{x2>2y[
[]Ea0jYu
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) nd1*e
{ ,~iAoxD5jY
} 0G 1o3[F
9F4|T7?
int main (void) 3NWAyCq-
{ 21 j+c{O
TestUnion pszobj("yuankai"); ;~;St>?\R\
TestUnion lobj(1234); g7F
Z -
cout<(pszobj)< cout< dfcG'+RU}
return 0; #^V"=RbD
} }(''|z#UE
\ChcJth@o<
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: Y'h'8
\
0/]vmDr
class TestUnion ".ZiR7Z:$Y
{ uoHhp 4>^
enum StoreType{Long,Const_CharP}; vsR ^aVwVZ
union DataUnion //不能匿名 LeCU"~
{ es]m 6A
DataUnion(const char*); //声明const char*构造函数 N8vl<
Mq
DataUnion(long); //声明long构造函数 c.WT5|:qw
const char* ch_; 9U*vnLB
long l_; M8 }M*\2
} data_; <k5~z(
StoreType stype_; RJ44o>L4O
TestUnion(TestUnion&); i6kyfOI
TestUnion& operator=(const TestUnion&); `s $@6r$
public: 6u}NI!he
TestUnion(const char* ch); 7:%K-LeaQu
TestUnion(long l); A-$BB=Ot
operator const char*() const {return data_.ch_;} i=+6R
operator long() const {return data_.l_;} I:"`|eHxv
}; AK =k@hT
5?MvO]_
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) <|iU+.j\
{//注意data_(ch),这里直接引用data_ ')V5hKb^
} /K<Nlxcm
_C\b,D}p
TestUnion::TestUnion(long l):data_(l),stype_(Long) Of=z!|l2
{//注意data_(l),这里直接引用data_ OHo0W)XUU
} s qKkTG3
{IvCe0`
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) R[;Z<K\Nn?
{
"kC>EtaX
} ?_r"Fg;"
NM Ajt>t
TestUnion::DataUnion::DataUnion(long l):l_(l) zOw]P6Gk
{ $@j7VPE
} /<Et
*1n:
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!