前言 CC&o pC
l*~O;do
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 {2 l35K=
9oBK(Sf@^
一、在union中存储对象 1c8Nr&Jl
MIma:N_c
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? UtPFkase
nX%b@cOXj
#pragma warning(disable : 4786) uqy&PS
#include =f0qih5.4
using namespace std; Rr#Zcs!G
!Q[j;f
class TestUnion y0s=yN_
{ HXV4E\JA
public: &JMp)zaI[
TestUnion(long l):data_(l) `R[cM; c2
{ 'kU5
}; w]L^)_'Th
int data_; 3{c6)vR2
}; =D-u".{
W
D 8
typedef union _tagUtype_ A1>fNilC9
{ wO<.wPa`
TestUnion obj; $fifx>!
}UT; 7p1f*N[X
k Il!n
int main (void) x -;tV=E}
{ n vzk P{
return 0; by}C;eN
} EPeKg{w
($QQuM=
"06t"u<%
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: I;xSd.-
{:=sCY!
class TestUnion [}>!$::Y
{ h;TN$ /
public: -sjyv/%_
int data_; [vv $"$z
}; ,X`w/ 2O
ya3k;j2C
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! T)c<tIr6
,J;Cb}
二、类中union的初始化 @!'rsPrI
CghlyT
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: \-?0ab3Z
L5[{taZ,
#pragma warning(disable : 4786) ehTrjb3k
#include KC+jHk
Ww=^P{q\
using namespace std; Gxh r0'
_v6x3 Z
class TestUnion LX'z7fh
{ m&MAA^ I
enum StoreType{Long,Const_CharP}; [?>\]
union &&PXWR!%]
{ -v %n@8p
const char* ch_; px${
"K<
long l_; .9NYa |+0
} data_; "ov270:
StoreType stype_; iW%~>`tT
TestUnion(TestUnion&); i(qZ#oN
TestUnion& operator=(const TestUnion&); NHaY&\
public: G)8v~=Bv
TestUnion(const char* ch); '3|fv{I
TestUnion(long l); { )g
$
operator const char*() const {return data_.ch_;} S(^HIJK
operator long() const {return data_.l_;} s$gR;su)g
}; Xb<>AzEM
7Is:hx|:
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) ]\Z8MxFD
{ Lv&9s
} ;mT
[s{ B vn
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) <N{wFvF
{ XCyU)[wY
} [$X^r<|P@
emSky-{$u
int main (void) +'|nsIx,
{ Sx8RH),k
TestUnion pszobj("yuankai"); @{>0v"@
TestUnion lobj(1234); pC~M5(F_
cout<(pszobj)< cout< -e4TqzRr
return 0; 1*GL;W~ix*
} }el7@Gv
Xj9\:M-
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: a[_IG-l|i4
${)oi:K@:
class TestUnion uG$*DeZti
{ 4mHk,Dd9,
enum StoreType{Long,Const_CharP}; )b?$
4<X^
union DataUnion //不能匿名 uv=a}U;
{ \Up~"q>Kb
DataUnion(const char*); //声明const char*构造函数 >[2;
DataUnion(long); //声明long构造函数 jiejs*
const char* ch_; W3zYE3DZf
long l_; h! Bg}B~
} data_; eDsB.^|l
StoreType stype_; 9:E: 3%%
TestUnion(TestUnion&); xtBu]I)%
TestUnion& operator=(const TestUnion&); ?W>`skQ
public: }K^v Ujl
TestUnion(const char* ch); IeZ9 "o h
TestUnion(long l); u69UUkG
operator const char*() const {return data_.ch_;} {/j gB"9
operator long() const {return data_.l_;} #;[0:jU0
}; h/Yxm2
kRjNz~g
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) ;}Ei #T,D
{//注意data_(ch),这里直接引用data_ ",xTgB3?V
} bvOnS0,y
k!ID
TestUnion::TestUnion(long l):data_(l),stype_(Long) YkFAu8b>
{//注意data_(l),这里直接引用data_ d#OAM;0}5
} -2[#1S*
+%f6{&q$
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) b"aF-,M>
{ hFo29oN
} ;F|#m,2Q-
riL|B3
TestUnion::DataUnion::DataUnion(long l):l_(l) KL6B!B{;
{ "O'c.v?{x
} 182g6/,
O/U? Wq
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!