前言 `+cc{k
Y S )Q#fP
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 B*#lkMr
zsnXPRF
一、在union中存储对象 WVl yR\.
GF[onfQY7
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? &|'k)6Rx
qg6283'?
#pragma warning(disable : 4786) ousvsP%'
#include n5h4]u
using namespace std; K9h{sC
IF-g %
class TestUnion wd&Tf
R4!
{ ew8f7S[
public: V'y,{YpP
TestUnion(long l):data_(l) $6Z@0H@X
{ 9M{z@H/
}; 53X H|Ap
int data_; X;/~d>@
}; G\4h4% a
2;N)>[3*J
typedef union _tagUtype_ *CG-F=
{ #wn`choT'
TestUnion obj; J+tpBPmb
}UT; _GSl}\
t_cNH@^3<3
int main (void) 5lehASBz
{ _s{on/u
return 0; #1c%3KaZI
} b`M 2VZu
R>1
q))rlMo
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: ZdQt!
*V}T}nK7
class TestUnion U'8+YAgc
{ 4 0as7.q
public: {T EF#iF
int data_; i!5zHn
}; CsfGjqpf
@ov*Fh
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Hxe!68{aR
dJ~AMol
二、类中union的初始化 O~Eju
? I7}4i7
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: .URCuB\{
-'ff0l
#pragma warning(disable : 4786) %dA6vHI,
#include aYc*v5QN3
RJ+i~;-
using namespace std; 'a8{YT4
Fo
K!JX*
class TestUnion -L=aZPW`M
{ >9F&x>~
enum StoreType{Long,Const_CharP}; UbDRzum
union ;jC}.]
_)w
{ 4O}ZnE1[
const char* ch_; 3^NHVg
long l_; BC|=-^(
} data_; h+ixl#:
StoreType stype_; x93t.5E6
TestUnion(TestUnion&); yb{ud
TestUnion& operator=(const TestUnion&); 1nHQ)od
public: BllS3I}V
TestUnion(const char* ch); =z_.RE
TestUnion(long l); iKs @oHW
operator const char*() const {return data_.ch_;} AXbDCDA
operator long() const {return data_.l_;} @K{1O|V
}; %#5yC|o9Pn
tkQ#mipAj
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) SvE3E$*
{ LHit9O[_/s
} &d1|B`gL|
OUo N
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) y; oPg4
{ fGK=lT$
} >iE/t$%1
UEkn@^&bg
int main (void) K ?R*
)_
{ !h\>[ O
TestUnion pszobj("yuankai"); 6k569c{7
TestUnion lobj(1234); ([vyY}43h
cout<(pszobj)< cout< 9
GEMmo3
return 0; @D$^-
S6
} Tvdg:[V<
D}.Pk>5
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: )w3?o#@
=8`!Ph@(
class TestUnion _[J @w .l(
{ J/OG\}
enum StoreType{Long,Const_CharP}; <]{$XcNm
union DataUnion //不能匿名 Yz"B
{ [WZGu6$SU
DataUnion(const char*); //声明const char*构造函数 J3
Y-d7=|
DataUnion(long); //声明long构造函数 k
:KN32%
const char* ch_; 3W&f^*
long l_; /=o~7y
} data_; Pn&