前言 aI%g2q0f
r(6Y*<
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 6w*dKInG[-
x/NfZ5e0X
一、在union中存储对象 O(#)m>A
EOIN^4V"
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? cbNTj$'b2u
F5LuSy+v
#pragma warning(disable : 4786) fX(3H1$"
#include {'NZ.
using namespace std; ls_'')yp
O_2pIbh
class TestUnion BHIRHmM<Y
{ Lco~,OE
public: ~d
o9;8v
TestUnion(long l):data_(l) TC N8a/@z
{ SAH-p*.
}; cpe+XvBuK
int data_; ZXu>,Jy
}; Y4OPEo 5o
H7?Vy bg~
typedef union _tagUtype_ ++bf#qS<8D
{ v6[!o<@"a
TestUnion obj; c%^7!FSg
}UT; 8{|8G-Mi
0Be<X
int main (void) )s)I2Z+
{ 6|K5!2
return 0;
d:_t-ZZo
} 0m7Y>0wC6T
S(o#K|)>
9?A)n4b;
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: ko5 @qNq
#Z}Rfk(~
class TestUnion )mI 05
{ 45=bGf#
public: r [9x
int data_; dl.N.P7}4
}; dah[:rP,n{
mH54ja2
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! }wWKFX
-<c=US
二、类中union的初始化 jTf@l?|
CHdX;'`*
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: aC^\(wp[
heltgRt
#pragma warning(disable : 4786) )bA;?i
#include Bt[/0>i
\@-@Y
using namespace std; kJWn<5%ayg
K}2Erm%A@y
class TestUnion ^aIPN5CK
{ qBU-~"2t
enum StoreType{Long,Const_CharP}; ~{?_p@&n
union /Y*WBTV'
{ 7@#>bE6
const char* ch_; 4]rnY~
long l_; pny11C
} data_; ylUrLQ\
StoreType stype_; #m lS}~n
TestUnion(TestUnion&); Hh%I0#
TestUnion& operator=(const TestUnion&); Jx_cf9{
public: _G_Cj{w
TestUnion(const char* ch); lackB2J9 A
TestUnion(long l); R7]l{2V#^
operator const char*() const {return data_.ch_;} TSA,WP\
operator long() const {return data_.l_;} =31"fS@
}; {.n"Z
V
@rI`~$
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) %`k6w3qI
{ [l:x'_y
} VJ84?b{c
W
y9_V
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ~aw.(A?MI
{ Dw|}9;5:A
} ioaU*%
OHv[#xGuV?
int main (void) 1ofKt=|=
{ |o,YCzy|5
TestUnion pszobj("yuankai"); s|@6S8E
TestUnion lobj(1234); -)s qc
P
cout<(pszobj)< cout< c@YI;HS_g
return 0; gep;{G}
} g6nkZyw
du+y5dw
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: k2E0/ @f{k
zFfoqb#*g
class TestUnion 5&xB6|k
{ =6xrfDbN8
enum StoreType{Long,Const_CharP}; &6DMk-
union DataUnion //不能匿名 1h(0IjG8
{ ?xK8#
DataUnion(const char*); //声明const char*构造函数 1m+p;T$
DataUnion(long); //声明long构造函数 X"MB|Ny
const char* ch_; so^lb?g
long l_; >82@Q^O
} data_; WJ)z6m]
StoreType stype_; w'L\?pI
TestUnion(TestUnion&); ~L]|?d"
TestUnion& operator=(const TestUnion&); |].pDwgt
public: \Fl+\?~D
TestUnion(const char* ch); h"lX4
TestUnion(long l); KgV3j]d
operator const char*() const {return data_.ch_;} u,F nAh?"
operator long() const {return data_.l_;} 2*rH?dz8E
}; >O1[:%Z1
IOTR/anu
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) I6~pV@h^=
{//注意data_(ch),这里直接引用data_ ~0?mBy!-O
} Xsa2(-
0YaA `
TestUnion::TestUnion(long l):data_(l),stype_(Long) k $M]3}$U
{//注意data_(l),这里直接引用data_ h
a|C&G
} .#wqXRd
uB |Ss
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) m_hN*v
Py
{ $`APHjijN
} $Vsk Ew"|M
sLh==V;9
TestUnion::DataUnion::DataUnion(long l):l_(l) t
c[n&X
{ D@G\7KH@
} )64@2~4y
BeCWa>54i
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!