前言 ByjfPb#
9mvy+XD
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 RgoF4g+@
*m"@*O'
一、在union中存储对象 DH.`
|E K6txRb
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? RbUir185Y
+DSbr5"VlB
#pragma warning(disable : 4786) )q'dX+4=eL
#include wrJQkven-
using namespace std; Q3ZGN1aX<
:gRrM)n
class TestUnion 2f:h z
{ ]Qe~|9I
public: ,'c%S|]U7
TestUnion(long l):data_(l) FiQ&g*=|
{ <tTNtBb
}; 1<@lM8&.kO
int data_; 7vgRNzZoq
}; iOa<=
3SWDPy
typedef union _tagUtype_ z]g#2xD2
{ Jy:@&c
TestUnion obj; n2*Ua/J-8
}UT; CxaI@+
7Z]?a
int main (void) %tkqWK:
{ qX5]\nX&G
return 0; Pq~#SxA~
} W\<OCD%X
rMG[,:V
WClprSl8
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: ui8$ F
"I*
;Uch
class TestUnion C,;<SV2#
{ @B{
public: bL<H$DB6
int data_; 5Zc
}; 8Ie0L3d-
|qpm
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! @I Y<i5(
Flpl,|n
a
二、类中union的初始化 ST#)Fl
,^4"e
(
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: b?=r%D->w
:fX61S6)
#pragma warning(disable : 4786) ce4rhtkV
#include q@1A2L\Om
.))k
using namespace std; M97+YMY)
49/2E@G4.
class TestUnion sfG9R"
{ dG3?(}p+
enum StoreType{Long,Const_CharP}; vIi&D;
union QN;NuDHN
{ &VjPdu57
const char* ch_; U#Kw+slM
long l_; ,-d2wzhW
} data_; S%]4['Y
StoreType stype_; 4myikeUR_
TestUnion(TestUnion&); 5Q}HLjG8Z
TestUnion& operator=(const TestUnion&); !b K;/)
public: #/(L.5d[
TestUnion(const char* ch); 6UN{Vjr%`
TestUnion(long l); (q7;/n
operator const char*() const {return data_.ch_;} N<(rP1)`v
operator long() const {return data_.l_;} ] %7m+-h@
}; Yo5ged]i
N+R{&v7=F%
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) lh0G/8+C
{ t(,2x%{
} brE%/%!e
!`U #Pjp.
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) V[44aN
{ 2DZ&g\|
} YS9)%F=X
'bji2#z[
int main (void) UT_t]m
{ 8/"uS ;yP
TestUnion pszobj("yuankai"); Pmuk !V}f
TestUnion lobj(1234); R $/q=*k
cout<(pszobj)< cout< Nde1`W]:
return 0; 50S*_4R
} H6#SP~V
O> wGJ.
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 5*"WS $
) \cnz
class TestUnion }sZy |dd
{ bnp:J|(ld
enum StoreType{Long,Const_CharP}; C`oB [
union DataUnion //不能匿名 }D~m%%,
{ &@&^k$du8q
DataUnion(const char*); //声明const char*构造函数 ='/#G0W
DataUnion(long); //声明long构造函数 }q/[\3
const char* ch_; 5',b~Pp
long l_; jN+2+P%OL
} data_; up3mum
StoreType stype_; D1fUEHB}A8
TestUnion(TestUnion&); )A;jBfr
TestUnion& operator=(const TestUnion&); )]}68}9
public: DqH]F S?]
TestUnion(const char* ch); \iwUsv>SB
TestUnion(long l); wzI*QXV2s
operator const char*() const {return data_.ch_;} /X\:3P
operator long() const {return data_.l_;} e+MsFXnB8
}; .fzns20u
+zFEx%3^
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) RoD9
{//注意data_(ch),这里直接引用data_ z\IZ5'
} ,+_gx.H2j
J:;nN-\j
TestUnion::TestUnion(long l):data_(l),stype_(Long) #b=*hi`E
{//注意data_(l),这里直接引用data_ No/D"S#
} Zvz}Z8jW
JZNvuP D
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) =?B[oq
{ `? f sU
} 0c#|LF_
X`}4=>
TestUnion::DataUnion::DataUnion(long l):l_(l) X 0m6<q
{ wB*}XJah
} P6ugbq[x#e
SQ`ec95',
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!