前言 XSC=qg$
Ysu\CZGX
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 '$OUe {j<
3A`Gx#
一、在union中存储对象 YTyrX
At\(/Zy
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 1<G+KC[F
x.-d)]a!
#pragma warning(disable : 4786) l\W|a'i
#include RKP,w%
using namespace std; jae9!Wi
?C[?dg{n
class TestUnion
E4 eXfu
{ 12lX-~[["
public: MoFM'a9
TestUnion(long l):data_(l) $ztsb V}
{ v\,N"X(,
}; :C>7HEh-2_
int data_;
;v.[aq
}; Gt.'_hf Js
wNHn.
typedef union _tagUtype_ sm-[=d%@L
{ 83c2y;|8
TestUnion obj; tfU*U>j
}UT; o=YOn&@%
hiS|&5#
int main (void) E@ :9|5
{ ~snj92K
return 0; m'NAM%$}J
} !vnC-&G
l?*DGW(t{
%(6IaqJ[
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: 2'@m'4-N
#`u}#(
class TestUnion lndz
{ '<o3x$6
*
public: ~W21%T+
int data_; [1vm~w'
}; c;kU|_
m,Y/ke\
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ZK]qQrIwy
/u$'=!<b;
二、类中union的初始化 ==[(Mn,%d
J|BElBY
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: ^^V3nT2rR3
vb=]00c
#pragma warning(disable : 4786) ~Y/A]N86,
#include tA#$q;S
*|=D 0
using namespace std; SxYz)aF~
$YX{gk>
class TestUnion 6X@z(EEL
{ 'u<e<hU
enum StoreType{Long,Const_CharP}; bX$z)]KKu
union U"7o;q
{ X_2N9$},
const char* ch_; )P(S:x'b0
long l_; v8-My1toV
} data_;
Lw\u{E@
StoreType stype_; .h W>#
TestUnion(TestUnion&); WPRk>j
TestUnion& operator=(const TestUnion&); DKS1Sm6d0
public: "\@J0|ppb
TestUnion(const char* ch); Ve(<s
TestUnion(long l); dCoP
qKy
operator const char*() const {return data_.ch_;} 9Rk(q4.OP
operator long() const {return data_.l_;} >.qFhO\1so
}; iLnW5yy
i?/Q7D<P
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) ^^v3iCT
{ J,Ki2'=
} 50MM05aC
Tm`@5
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) rT `sY
{ xq;>||B
} >2s6Y
:=B.)]F.)
int main (void) ^(TCUY~f&
{ J920A^)j!
TestUnion pszobj("yuankai"); 0HWSdf|w
TestUnion lobj(1234); K F'fg
R
cout<(pszobj)< cout< c$ /.Xp
return 0; ^dpM2$J
} w<B
S
'aEK{#en
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: *B3f ry
?c?@j}=?yY
class TestUnion
:Hq%y/
{ ^P9mJ:
enum StoreType{Long,Const_CharP}; k\O<pG[U
union DataUnion //不能匿名 Kk},
PU=
{ ahXcQ9jzFi
DataUnion(const char*); //声明const char*构造函数 KRxJ2
DataUnion(long); //声明long构造函数 G|jHic!
const char* ch_; >l 0aME@-0
long l_; (/uN+
} data_; H}r]j\
StoreType stype_; h>bjG
TestUnion(TestUnion&); 2;sTSGDG
TestUnion& operator=(const TestUnion&); Ou1kSG|kM
public: >c0leT
TestUnion(const char* ch); d9JAt-6z2
TestUnion(long l); RP2$(%
operator const char*() const {return data_.ch_;} O.FTToh<
operator long() const {return data_.l_;} gba1R
}; rCa]T@=
3YLK?X8
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) P1OYS\
{//注意data_(ch),这里直接引用data_ drAJ-ii
} !!L'{beF
6|p8_[e`
TestUnion::TestUnion(long l):data_(l),stype_(Long) ky|k g@n{
{//注意data_(l),这里直接引用data_ ;}6wj@8He
} L&+k`b
0i}.l\
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) P\dfxR;8%
{ |\Gkhi>;
} N$>Ml!J
j?C[ids<
TestUnion::DataUnion::DataUnion(long l):l_(l) RK@K>)"f
{ o%Q9]=%!
} R7IFlQH%
s[7$%|~W
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!