前言 ~?(N
i-6Z"b{
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 %$b:X5$Z
>p"c>V& 8
一、在union中存储对象 #'y#"cmQ.
>3Eo@J,?d
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? <~WsD)=$
@ta7"6p-i@
#pragma warning(disable : 4786) *6VF
$/rP
#include M]J^N#
using namespace std; :5{wf Am
>6?__v]9G
class TestUnion i*Z"Me
{ RNe^;
B
public: o7$'cn
TestUnion(long l):data_(l) @<elq'2
{ f.9SB
}; 3qf
Ym}d
int data_; OOo3G~2r
}; ~Yy>zUH^X
Y/*mUS[oa
typedef union _tagUtype_ Ys\Wj%6A
{ hbY5l}\5
TestUnion obj; 6}FP
}UT; W>j !Q^?
MB~=f[cUnd
int main (void) !*7 vFl
{ '2 PF
return 0; N$U$5;r~`
} 3R.W>U
G6$kv2(k`@
5?]hd*8
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: AT2n VakL
?j"KV_
class TestUnion Q$zO83
{ {?:X8&Sf
public: 7+\+DujE$
int data_; ,g2ij
}; }&wUr>=
JzQ )jdvp
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! =A83W/4
VHIOwzC
二、类中union的初始化 JvVWG'Z"
3h$6t7=C
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: Ab{ K<:l
PoG-Rqe
#pragma warning(disable : 4786) x|pg"v&[
#include zh8nc%X{
1H6<[iHW
using namespace std; TFlet"ge=
)48QBz?
class TestUnion Rh_np
{ M
l Jo`d
enum StoreType{Long,Const_CharP}; _Xk.p_uh
union 1g8_Xe4
{ F8jd'OR
const char* ch_; %A1o.{H
long l_; &$`P,i 1)
} data_; gOSJM1Mr3
StoreType stype_; |H;F7Y_
TestUnion(TestUnion&); zv0l,-o
TestUnion& operator=(const TestUnion&); J;.wXS_U8
public: ,,%i;
TestUnion(const char* ch); /Z'L^L%R
TestUnion(long l); Xg|B \\
operator const char*() const {return data_.ch_;} le/,R@]B9
operator long() const {return data_.l_;} ,)Me
}; ?XrQ53
l;R%= P?'F
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) $'BSH4~|.
{ $rv8K j+
} 7}f}$1
V58wU:li
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) [^Os kJ4
{ /uPcXq:L~
} l{I6&^!KS
!h"Kq>9T
int main (void) l=S 35og
{ I`-8Air5f
TestUnion pszobj("yuankai"); +)!Y rKuu
TestUnion lobj(1234); #lmB
AL~3
cout<(pszobj)< cout< gd%NkxmW
return 0; i2E)P x
} K1mPr^3rC
nw -xSS{
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: i
UCXAWP
ciBP7>'::
class TestUnion hn5h\M?
{ fd+hA
enum StoreType{Long,Const_CharP}; (D#B_`;-
union DataUnion //不能匿名 HW3 }uP\c
{ d"}k!
0m
DataUnion(const char*); //声明const char*构造函数 zKw`Md
DataUnion(long); //声明long构造函数 w~(1%p/
const char* ch_; zL$@`Eh-KP
long l_; /Y9>8XSc
} data_; HJLu'KY}
StoreType stype_; N4^-`
TestUnion(TestUnion&); ]NUl9t*N4
TestUnion& operator=(const TestUnion&); U{7w#>V
.
public: nxUJN1b!N
TestUnion(const char* ch); 7&t-pv92*
TestUnion(long l); ykl
.1(
operator const char*() const {return data_.ch_;} Z,sv9{4r
operator long() const {return data_.l_;} g[1gF&
}; }SX,^|eN
(U&tt]|
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) QKyo`g7
{//注意data_(ch),这里直接引用data_ 1n=lqn/
} .u*0[N
j/R[<47
TestUnion::TestUnion(long l):data_(l),stype_(Long) DK$X2B"c V
{//注意data_(l),这里直接引用data_
z_F-T=_
} (KFCs^x7wG
a][f
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) \]</w5 Pi,
{ )Ub_@)X3%l
} }p}[j t
HBy[FYa4
TestUnion::DataUnion::DataUnion(long l):l_(l) SQ44
{ 2;zb\d
} G0/4JSH
H<VTa? n
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!