前言 f|1FqL+T]
Dohe(\C@
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 r74w[6(
s(Bi&C\
一、在union中存储对象 >M85xjXP
7gmMqz"z(>
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? *`'%tp"'+
,8?*U]}
#pragma warning(disable : 4786) &?sjeC_
#include usf(U>
using namespace std; =C1Qo#QQ%
([o:_5/8I
class TestUnion ]=<@G.[=
{ vg1s5Yqk
public: ,?~,"IQyi[
TestUnion(long l):data_(l) pR>QIZq<gT
{ %~XJwy-
}; z4:09!o_
int data_; pvxqeC9`
}; 2dW-WHaM
g c=|<(
typedef union _tagUtype_ -3U}
(cZ*
{ 7B"aFnK;[J
TestUnion obj; |noTIAI
}UT; $:Zxb
lfd{O7 L0b
int main (void) Z i&X ,K~
{ 3PeJPw
return 0; ED&KJnquWJ
} W\Y
4%y}
q`zR 6
S^=/}PT'
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: 30`H
Xv@
n :kxG
class TestUnion ~36XJ
{ <QLj6#d7Y
public: )@M|YM1+
int data_; *9^k^h(r&4
}; me\)JCZpb{
5*Iz3vTq
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ')~HOCBSE
s5#g[}dj
二、类中union的初始化 824%]i3
T,@7giQg@
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: 1H@F>}DP
8Wp1L0$B
#pragma warning(disable : 4786) ;%9ZL[-
#include [/]3:|
!Xce iQu
using namespace std; f2f$aZ
jZyh
class TestUnion Z6pDQ^Ii
{ f89<o#bm7h
enum StoreType{Long,Const_CharP}; 36UWoo
union Yb/^Qk59
{ ^>uGbhBp
const char* ch_; C.p*mO&N
long l_; w=2X[V}
} data_; w`:KexD+
StoreType stype_; .1M>KRSr,
TestUnion(TestUnion&); ePdzQsnVe
TestUnion& operator=(const TestUnion&); k Er7,c
public: :D-vE7
TestUnion(const char* ch); 4}j}8y2)H
TestUnion(long l); 5@5="lNjS
operator const char*() const {return data_.ch_;} N`fY%"5U>
operator long() const {return data_.l_;} LnIJw D
}; X/"H+l
FiL
JF!
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) 1N*~\rV*?
{ <3OV
} |[ofc!/
2V 'Tt3
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) =z.AQe+
{ 2Ta F7Jn
} =wc[r?7
Hq8.O/Y"=
int main (void) G9Ezm*I;:
{ #xB%v
TestUnion pszobj("yuankai"); GV/FK{v5
TestUnion lobj(1234); RzRLrfV
cout<(pszobj)< cout< ~coG8r"o
return 0; S?$T=[yY)
} )I_I?e
Kz;VAH
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下:
1Btf)y'
G&-h,"yo^
class TestUnion Stpho4+/y
{ ) 'KHUa9
enum StoreType{Long,Const_CharP}; Uy=eHwU?J
union DataUnion //不能匿名 "w1jr 6"
{ H*IoJL6
DataUnion(const char*); //声明const char*构造函数 .=S{
DataUnion(long); //声明long构造函数 )vzT\dQ|
const char* ch_; @"0qS:s]X
long l_; qB`P7!VN^]
} data_; i"@?eq#h
StoreType stype_; V;=T~K|)>
TestUnion(TestUnion&); !h\3cs`QU
TestUnion& operator=(const TestUnion&); ;?9~^,l
public: g!UM8I-$
TestUnion(const char* ch); hJ :+*46
TestUnion(long l); !j@ 8:j0WY
operator const char*() const {return data_.ch_;} q\<vCKI-^
operator long() const {return data_.l_;} A`Nb"N$H13
}; 4g9VE;Gd
6(=:j"w0
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) TvR2lP
{//注意data_(ch),这里直接引用data_ 8wd2\J,]
} gS ]'^Sr
dewu@
TestUnion::TestUnion(long l):data_(l),stype_(Long) $?YkgK
{//注意data_(l),这里直接引用data_ oR }
} 2}AV_]]
fA^ O
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) M?o`tWLhF
{ =O<BMq{d
} vPi+8)
}PJ:9<G
y
TestUnion::DataUnion::DataUnion(long l):l_(l) 2ou?:5i
{ 60Z)AQs;+J
} CpXv?uU
mB\|<2
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!