前言 1#'wR3[+
<AVpFy
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 p"T4;QBxQ
G*QQpSp
一、在union中存储对象 gC 4w&yL
4l|Am3vzX
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? _]\mh,}
,=mn*
#pragma warning(disable : 4786) 43eGfp'
#include {E9Y)Z9
using namespace std; |89`O^
Zy'bX* s|
class TestUnion ~&pk</Dl
{ GcKJpI\sB
public: eaI&DP
TestUnion(long l):data_(l) .Ee8s]h5W
{ %>f:m!.
}; csC3Wm{v
int data_; "0
v]O~s
}; u@o3p*bQ
fROhn}<**[
typedef union _tagUtype_ aAX 8m
{ s:jwwE2
TestUnion obj; HJ2]xe09
}UT; Z#F2<*+Pe
i_MDLS>-
int main (void) p\(%bO
{ A >x{\
return 0; }, ]W/
} 9TF[uC)-2
DI*xf
Kt
a`T{5*@
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: rO-Tr
}p#S;JZRu+
class TestUnion (\Dd9a8V-
{ E_h 9y
public: $,
=n
int data_; r6^DD$X
}; 0c]Lm?&
6gp3n;D
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! IlwY5i L
E_xpq
二、类中union的初始化 mFvw s
`T-(g1:9
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: @A)gsDt9A
[p]Ayo$~
#pragma warning(disable : 4786) 6Up,B=sX0
#include w_9:gprf
5SDHZ?h
using namespace std; ;1BbRnCr
2qN6{+]
class TestUnion D3I;5m`_
{ nGRF<2!
enum StoreType{Long,Const_CharP}; Z!#zr@'k
union d/;oNC+
{ }ulFW]A^7
const char* ch_; 39u!j|VH
long l_; u tQ_!3u
} data_; gP<l
StoreType stype_; QtRKmry{
TestUnion(TestUnion&); TIS}'c'C
TestUnion& operator=(const TestUnion&); ?4xTA
public: =6? 3c\
TestUnion(const char* ch); H*l8,*M}
TestUnion(long l); ~_R=2t{u_
operator const char*() const {return data_.ch_;}
|,.glL
operator long() const {return data_.l_;} {4#'`Eejj
}; WhvO-WF
`/#6k>
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) E9|i:
{ wKwireOs
} '*22j ]
rQ/S|gG
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) Ua(!:5q?
{ 8TuOf(qE
} Z,ag5 w`]L
@ij}|k%*
int main (void) nE,"3X"
{ @
j'I
TestUnion pszobj("yuankai"); ji">} -
TestUnion lobj(1234); `57ffQR9
cout<(pszobj)< cout< Dtelr=/s
return 0; M@
mCBcbN
} KO:o GUR
IX-ir
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: VTD'D+t
:eDwkzlHH
class TestUnion H+-9R
{ pi+m`O
enum StoreType{Long,Const_CharP}; 1 [dza5
union DataUnion //不能匿名 =`g+3
O;<
{
%<K`d
DataUnion(const char*); //声明const char*构造函数 c^I_~OwaE
DataUnion(long); //声明long构造函数 7Ij FSN>
const char* ch_; EpS"NQEe
long l_; J}lBKP:-*
} data_; .|cQ0:B[
StoreType stype_; 7+@:wX\
TestUnion(TestUnion&); l9# v r
TestUnion& operator=(const TestUnion&); ~^Gk7
public: @TsOc0?-
TestUnion(const char* ch); v dyu =*Y
TestUnion(long l); iYBs )
operator const char*() const {return data_.ch_;} r\a9<nZ{
operator long() const {return data_.l_;} wn5CaP(]8
}; ]{Iy<
&rk/ya[
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) vxK}f*d
{//注意data_(ch),这里直接引用data_ N}Z"$4
} {B uh5U,
$5|/X&"O)/
TestUnion::TestUnion(long l):data_(l),stype_(Long)
>OmY
{//注意data_(l),这里直接引用data_ e<>(c7bF
} +ImPNwrY
>Xh9{/o
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) :*#I1nb$
{ =((#k DrN
} 'ym/@h7h
G^5}T>TV
TestUnion::DataUnion::DataUnion(long l):l_(l) z1_\P) M
{ StA5h+[m
} $
^m_M.1
JT, 8/o
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!