前言 dihjpI_
kRJ4-n^@><
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 21X`h3+=
Dim>
7Wbh
一、在union中存储对象 4BL;FO
N2r/ho}8
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? uN*KHE+h
;bzX%f?|G
#pragma warning(disable : 4786) F9"w6;hh
#include Ex amD">T
using namespace std; Uu
s.
;*TIM%6#
class TestUnion S[3iA~)Z-
{ {$D,?V@%_
public: >et-{(G
TestUnion(long l):data_(l) *iO u'
{ tC?=E#3V
}; n:
ui
int data_; 5|0,X<&
}; MM_k
]-7
#p(h]T32
typedef union _tagUtype_ _9 .(a
{ r|Z3$J{^"
TestUnion obj; $``1PJoi
}UT; !LMN[3M_
+j_;(Gw7
int main (void) |y;}zQB-dH
{ 3981ie
return 0; VZr>U*J[:
} {Bs~lC$
QfM zF
OVzt\V*+%W
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: e~%
;K4
Pt:e!qX)
class TestUnion RcG0 8p.)
{ -H^oXeN
public: E907fX[R~
int data_; Ix@&$!'k
}; >zsid:
/-_=nf}w
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! x5`br.b
H`bSYjgM!
二、类中union的初始化 K%<j=c
:NHH
Dl
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: xJ^>pg8
G@FI0\t
#pragma warning(disable : 4786) oBQ#eW aY
#include $E<Esf$
fqX"Lus `=
using namespace std; ZRxZume<f
00I}o%akO
class TestUnion ?&G`{Ey
{ E1dD7r\
enum StoreType{Long,Const_CharP}; ^'CPM6J
union n~"$^Vr
{ <?-YTY|
const char* ch_; `g8E1-]l
long l_; f0<hE2
} data_; fH`P[^N
StoreType stype_; =ph&sn$;L
TestUnion(TestUnion&); ,g-EW
jN
TestUnion& operator=(const TestUnion&); rk+#GO{
public: ~7~~S*EQ
TestUnion(const char* ch); ](tx<3h
TestUnion(long l); {2/LRPT
operator const char*() const {return data_.ch_;} <DKS+R
operator long() const {return data_.l_;} 5$DHn]
}; q"O.Cbk
|b-9b&
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) `p;eIt
{ M;cO0UIwO
} D']ZlB'K
bwVPtu`
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) j?y LDLj
{ 5>3}_
} '1,,)U#6E
5w %_$x
int main (void) t*@2OW`!
{ rg0ma
TestUnion pszobj("yuankai"); Q9I
j\HbA"
TestUnion lobj(1234); sK{l 9
cout<(pszobj)< cout< 8^Hn"v
return 0; Vfv@7@q
} 56^+;^f^`
M02uO`Y9
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 4S~o-`&W
h\plQ[T
class TestUnion 8N:owK
{ &_JD)mM5
enum StoreType{Long,Const_CharP}; 4}_O`Uxh
union DataUnion //不能匿名 Gl1jxxd
{ ,Jc m+Wb
DataUnion(const char*); //声明const char*构造函数 `cPywn@uGZ
DataUnion(long); //声明long构造函数 REZJ}%}/
const char* ch_; S3L~~X/=
long l_; uwRr LF
} data_; fLV"T_rk
StoreType stype_; %6AW7q
t
TestUnion(TestUnion&); 4}`
TestUnion& operator=(const TestUnion&); pF
^#}L
public: (D@A74q\'
TestUnion(const char* ch); /R>nr"
TestUnion(long l); MCU_Z[N#10
operator const char*() const {return data_.ch_;} |F9z,cc"
operator long() const {return data_.l_;} v9Xp97J2
}; \Mg`(,kwe
e]jH+IR:>
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Bo<>e~6P
{//注意data_(ch),这里直接引用data_ R!l:O=[<
} u:aW 8
TCT57P#b
TestUnion::TestUnion(long l):data_(l),stype_(Long) SQeRSz8bK4
{//注意data_(l),这里直接引用data_ YF+n
b.0.
} dw.F5?j`b
n@ w^V
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) sAg Kg=)
{ P&Pj>!T5
} mv5n4mav
?"z]A7<Hj
TestUnion::DataUnion::DataUnion(long l):l_(l) mxb06u_
{ n}s~+USZX
} h" H2z1$
k}KC/d9.z
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!