前言 *%JncK'
cP[3p:
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 m&)5QX
L(tA~Z"k
一、在union中存储对象 !;'.mMO&%
r&AX
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? =2HR+
odxsF(Q0p
#pragma warning(disable : 4786) M{Ss?G4H
#include J8|F8dcz
using namespace std; 2UYtFWB9o
F,0@z/8a
class TestUnion >sAZT:&gv
{ sjOyg!e
public: :+;AXnDM~
TestUnion(long l):data_(l) l?CUd7P(a
{ C`F*00M{
}; e(/~;"r{
int data_; l"%|VWZ{iq
}; ZA@QP1
b&.j>=
typedef union _tagUtype_ !a&@y#x
{ V|.3Z\(
TestUnion obj; 5>.)7D%
}UT; [uxhdR`T
m=&j2~<i
int main (void) ODn6%fp%
{ rK%<2i
return 0; y7#$:+jQv
} zNT~-
y(&JE^GfX
;Ab`b1B
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: '0_Z:\ laU
%MyA;{-F6
class TestUnion T.kmoLlH
{ `+17x<N
public: S -j<O&h~C
int data_; .uzg2Kd_
}; ]_NN,m>z
"oZ]/(
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! %FnaS
u
m%ZJp7C
二、类中union的初始化 J_tj9+r^
D*+uH;ws
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: "@!z+x[8
]@OGp:Hz
#pragma warning(disable : 4786) n*-t
=DF
#include m#SDB6l
hQ&S*f&='
using namespace std; Dt,b\6
& f7 {3BK
class TestUnion yoTbIQ
{ ?29zcuRaru
enum StoreType{Long,Const_CharP}; WjZJQK
union t1p}
{ gd'#K~?
const char* ch_; BCB"&:}
long l_; wH1E7LY|R
} data_; `<ITLT
StoreType stype_; J<x?bIetj
TestUnion(TestUnion&); U,"lOG'
TestUnion& operator=(const TestUnion&); i:`ur
public: $Z)Dvy|
TestUnion(const char* ch); XQ.czj
TestUnion(long l); 8cn)ox|J[
operator const char*() const {return data_.ch_;} .+3= H@8h
operator long() const {return data_.l_;} [\CQ_qs|
}; Ms5m.lX
K1>.%m
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) %]%.{W\j3
{ q+XL,E
} v{Cts3?Br
}$u]aX<
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) %C=^
h1t%
{ "sF&WuW|
} d;&'uiS
g~_cYy
int main (void) 24{!j[,q@
{ f !t2a//
TestUnion pszobj("yuankai"); F\!;}z
TestUnion lobj(1234); =W)Fa6P3j(
cout<(pszobj)< cout< hGi"=Oud2
return 0; JDv7jy
} K[Rl R+j
M.1bRB
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 3#R~>c2
b Jt397
class TestUnion @O+yxGA
{ }h<\qvCcU
enum StoreType{Long,Const_CharP}; 5;{d*L
union DataUnion //不能匿名 :)}iWKAse
{ :T3I"
DataUnion(const char*); //声明const char*构造函数 )
Ph.
DataUnion(long); //声明long构造函数 k$kq|
const char* ch_; NGB%fJ
long l_; %Qc#v$;+J
} data_; KquHc-fzqr
StoreType stype_; ^7v}wpwX\
TestUnion(TestUnion&); Z"#ysC
TestUnion& operator=(const TestUnion&); tr"iluwGc
public: >XP]NY}Po[
TestUnion(const char* ch); i' J.c4
TestUnion(long l); kRNr`yfN
operator const char*() const {return data_.ch_;} 1\q(xka{
operator long() const {return data_.l_;} Sr~zN:wn
}; }Q_IqI[7
yrO'15TB
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) FT73P0!8.
{//注意data_(ch),这里直接引用data_ i_ws*7B<
} z<c^<hE:l
%Rv&VFg
TestUnion::TestUnion(long l):data_(l),stype_(Long) BDZB;DPb
{//注意data_(l),这里直接引用data_ eKn&`\j6
} %)*!(%\S*3
W"4E0!r
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) {EbR
=
{ STu!v5XY}-
} g[Ah>
5
;[WW,,!Y
TestUnion::DataUnion::DataUnion(long l):l_(l) %@q52ZQ
{ tu6oa[s
} RL |.y~
9Q-/Yh
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!