前言 mUyv+n,
3ZL7N$N}7
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 tW.>D;8
d)1sP0Z_@
一、在union中存储对象 06 Esc^D
&tz%WW%D8
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? /Np"J
b/,!J]W
#pragma warning(disable : 4786) cvV?V\1f
#include 3b)T}g
using namespace std; VgsCwJ9w
h"1"h.
class TestUnion *!]Epb
{ 199hQxib:
public: _2X6bIE
TestUnion(long l):data_(l) 8wpwJs&V
{ @~#79B"9&
}; AzO3 (1:
int data_; EXW
6yXLV
}; XBWSO@M'
O4d^ig-xaH
typedef union _tagUtype_ xDA,?i;T
0
{ f+TBs_
TestUnion obj; z?uQlm*We
}UT; Hrg=sR
-~ O;tJF2
int main (void) 9g&)6,<
{ fo\J \
return 0; ?Y6la.bc{
} >c
y.]uB
F `pyhc>1;
-=Eq/su%
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: &>zy_)
?fa,[r|G
class TestUnion U~#^ ^
{ >RL6Jbo|
public: `k{ ff
int data_; w[YkTv
}; v`+n`DT
vgQhdtt
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! jU4)zN/`r
G9'YgW+$7
二、类中union的初始化 +ersP@G
ksOANLRN
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: ( ln
(m3I#L
#pragma warning(disable : 4786) :S99}pgY
#include 9u7n/o&8v6
M ,_^hm7
using namespace std; j^$3vj5E[
JM+sHHs
class TestUnion xH`j7qK.
{ }OP%p/eY
enum StoreType{Long,Const_CharP}; ^{fi^lL=
union 4-d99|mv
{ zN)|g
const char* ch_; dW{o+9 nw
long l_; Xs%R]KOwt
} data_; {b-0_
StoreType stype_; # McK46B z
TestUnion(TestUnion&); (ju
aDn)
TestUnion& operator=(const TestUnion&); N1+4bR
public: r>Qyc
TestUnion(const char* ch); rq'##`H
TestUnion(long l); 3vRLg b
operator const char*() const {return data_.ch_;} #zSi/r/=1
operator long() const {return data_.l_;} 9#s95RO
}; >Oi2gPA
x<{;1F,k3
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) &w;^m/zP3
{ >G4HZE
} 9&XV}I,~?|
h$aew63
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) VM<oUKh_3
{ V
4\^TO`q=
} 1%/ NL?8#
hk"9D<&i>b
int main (void) a_ 9 |xI
{ 6_9:Eb=^v!
TestUnion pszobj("yuankai"); 6cQeL$,SQ
TestUnion lobj(1234);
CSG+bqUG
cout<(pszobj)< cout< G%j/eTTf
return 0; \~z?PA.$
} \'It,PN
=2;mxJ# o
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: '.%iPMM
W>q*.9}Y"
class TestUnion 5I)~4.U|,m
{ U+9-li
enum StoreType{Long,Const_CharP}; j1;_w
union DataUnion //不能匿名 ?O<`h~'$+
{
(^tr}?C
DataUnion(const char*); //声明const char*构造函数 >Bh)7>`3c
DataUnion(long); //声明long构造函数 ]5o0
const char* ch_; _A;vSp.`
long l_; eN<>#:`
} data_; 7,W]zKH
StoreType stype_; ;<bj{#mMv
TestUnion(TestUnion&); "o^bN 9=
TestUnion& operator=(const TestUnion&); nl)_`8=
public: "q9~C
TestUnion(const char* ch); WIEx
'{
TestUnion(long l); a%MzNH
operator const char*() const {return data_.ch_;} @O}IrC!bf
operator long() const {return data_.l_;} $tDCS
}; koncWyW
v2M"b?Q
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) =2.tu*!C
{//注意data_(ch),这里直接引用data_ zJnL<Q
} )d770Xg+
^Txu~r0@
TestUnion::TestUnion(long l):data_(l),stype_(Long) xUiWiOihr6
{//注意data_(l),这里直接引用data_ t-*VsPy
} "4Lg8qm
JAGi""3HG
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 1AV1d%F
{ g{g`YvLu^
} gZ`32fB%
Gsds!z$
TestUnion::DataUnion::DataUnion(long l):l_(l) q:`77
{ pgz:F#>
} klK-,J
ot|N;=ZKo
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!