前言 v K{2
H(;@7dh
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 [z!m
Ew0)MZ.#
一、在union中存储对象 v`K%dBa
8gNTW7W/
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? YT8q0BR]
:N<Qk
#pragma warning(disable : 4786) _fk}d[q0
#include gN<7(F
using namespace std; ]8%E'd
PsUO8g'\
class TestUnion 82,^Pu
{ RTlC]`IGT
public: )zO|m7
TestUnion(long l):data_(l) 8F>9CO:&N
{ ?{ '_4n3O
}; T`@brL
int data_; X% 05[N
}; <J%Z?3@T
@>(JC]HtR
typedef union _tagUtype_ #"-_ ~
{ KH#z =_
TestUnion obj; 5nib<B%<V
}UT; ;!f~
`r1j>F7Xb
int main (void) VB90 5%
{ F#|y,<}<
return 0; kO}%Y?9d
} 1y:fH4V
Fq~Zr;A
M 0}r)@
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: ]d(Z%
Vq0X:<9
class TestUnion F_:Wu,dUZ
{ cr -5t4<jK
public: KJJ:fG8'
int data_; j_,/U^Ws|f
}; E8av/O
VUd
lfb+ )s
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Mhn1-ma:
@$kO7k0{g
二、类中union的初始化 \2+ngq)
CRCy)AS,t
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: uq[5 om"
.Bkfe{^
#pragma warning(disable : 4786) l4$ sku-
#include Eg1TF oIWl
??e|ec2%
using namespace std; CC^]Y.9
<EqS
,cO^
class TestUnion Dn<3#V
{ )6%*=-
enum StoreType{Long,Const_CharP}; e=h-}XRC
union 5D<Zbn.>q
{ -cU bIbW
const char* ch_; e%pohHI
long l_; HdlOGa6C
} data_; G0h&0e{w
StoreType stype_; KsIHJr7-
TestUnion(TestUnion&); ,k_ b-/
TestUnion& operator=(const TestUnion&); <=_!8A
public: BYdGK@ouk
TestUnion(const char* ch); 8aHE=x/TL
TestUnion(long l); [L-wAk:Fb
operator const char*() const {return data_.ch_;} qPz_PRje
operator long() const {return data_.l_;} qGN>a[D
}; *>?N>f"
4P?`<K'
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) M^\`~{*T
{ 6?5dGYAX<
} 6H2Bf*i
-}4CY\d6'
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) H[:lQ\
{ }U=}5`_]D
} Xk!{UxQKQ
:mDOqlXW/
int main (void) 4/{pz$
{ OH`zeI,[*
TestUnion pszobj("yuankai"); :55a9d1bL
TestUnion lobj(1234); S=S/]]e
cout<(pszobj)< cout< 13 L&f\b
return 0; 2V;{@k
} %w>3Fwj`z
Iu0GOy*[
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: Zc38ht\r;
7)}_'p
class TestUnion \nyqW4nTm
{ %I`'it2d
enum StoreType{Long,Const_CharP}; lAG@nh^
union DataUnion //不能匿名 wvisu\V
{ 28M^F~0
DataUnion(const char*); //声明const char*构造函数 9Bpb?
DataUnion(long); //声明long构造函数 ?{ \7th37
const char* ch_; dpchZ{
long l_; 416}# Mk
} data_; Pbbi*&i
StoreType stype_; }LS.bQKqi,
TestUnion(TestUnion&); 3%Q<K=jy
TestUnion& operator=(const TestUnion&); |Wck-+}U
public:
,_V/W'
TestUnion(const char* ch); POc<XLZB
TestUnion(long l); Q;l%@)m+~
operator const char*() const {return data_.ch_;} N!<l~[rc
operator long() const {return data_.l_;} x ]}'H
}; zN5};e}^v
<]z4;~/&
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) IC"ktv bHz
{//注意data_(ch),这里直接引用data_ 2h<_?GM\s
} si~zg\uY
4W2.K0Ca
TestUnion::TestUnion(long l):data_(l),stype_(Long) _IEbRVpb
{//注意data_(l),这里直接引用data_ ~x4]p|)</
} @6|0H`kv
[oBRH]9cq
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) Ivcy=W=Jk
{ h5@7@w%
} +>eX1WoTy
LZG(T$dI
TestUnion::DataUnion::DataUnion(long l):l_(l) !s$1C=z5u
{ bUy!hS;s
} dtV*CX.D.7
rFt+Y})
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!