前言 g@KS\.m]
=)(sN"%
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 -.i1l/FzP
PtwE[YDu
一、在union中存储对象 :W 8DgL>l
B?$pIG^Mn
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? YM/^-[k3
sf@g $
#pragma warning(disable : 4786) @y{Whun~
#include ZOyq{w!2
using namespace std; "{AS5jw
&3'II:x(
class TestUnion B7_:,R.l
{ HmAA?J}
public: /|P&{!
TestUnion(long l):data_(l) -@<k)hWr
{ >Ix)jSNLgo
}; 9^3y\@ m
int data_; aZ@Ke$jD
}; Z,_yE*q
N:Q}Lil
typedef union _tagUtype_ 00n6v;X
{ bxK1v7
TestUnion obj; `4gm'C
}UT; }`\+_@w
gNo.&G [
int main (void) ~;3N'o
{ }I9\=jT
return 0; $+R0RqV$V~
} TCv}N0
}q)oLC
a$l/N{<.
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: J}nE,U2
uJ {N?
class TestUnion V2V^*9(wu@
{ XW%!#S&;X
public: Cj31'
int data_; *3s4JK
}; Y*dzoN.sW
4-lEo{IIM
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! d {T3
;sS N
二、类中union的初始化 YJ_LD6PL9
"fL:scq@0
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: th2a'y=0
ZH~ T'Bg
#pragma warning(disable : 4786) :W? 7J"
#include ?6; +.h\
K#}DXq
using namespace std; / ~K-0K#w
0Zs}y\J`
class TestUnion BI3Q~ADV
{ MrXhVZ"d*
enum StoreType{Long,Const_CharP}; L/_OgL]YdI
union 7eqax33f
{ (B}+uI{
const char* ch_; r~si:?6:
long l_; #-+!t<\
} data_; /q ;MihK
StoreType stype_; 6dt]$
TestUnion(TestUnion&); ?R&,1~h
TestUnion& operator=(const TestUnion&); ;%"UZ~]f
public: o=X6PoJN_
TestUnion(const char* ch); {]n5h#c 5*
TestUnion(long l); @K7#}7,t
operator const char*() const {return data_.ch_;} U:M?Ji5CY
operator long() const {return data_.l_;} p%jl-CC1
}; 7^A;.x
Bq#?g@V
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) weEmUw Z
{ rLw,?
} x24
.>Gq/[c0|
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) AhZ8B'Ee
{ s"*zyLUUo
} k+f!)7_
:[ F`tDL
int main (void) S>Z V8
{ Ysz{~E'
TestUnion pszobj("yuankai"); )3V5P%Q
TestUnion lobj(1234); HcXyU/>D
cout<(pszobj)< cout< FYFP6ti
return 0; \H!ECTI
} hyH "
n\Uh5P1W"
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: ):
R+
lwOVX
class TestUnion "6Hka{
{ ==F[5]?
enum StoreType{Long,Const_CharP}; R%Gh4y\nF
union DataUnion //不能匿名 RX P 0
4
{ (Eq0 |"cj
DataUnion(const char*); //声明const char*构造函数 \Azl6`Em
DataUnion(long); //声明long构造函数 x00"d$!
const char* ch_; AkrUb$ }
long l_; o$FqMRep
} data_; )q&=x2`
StoreType stype_; s?@{
TestUnion(TestUnion&); HF"
v
\
TestUnion& operator=(const TestUnion&); {w$1_GU
public: 7SE\(K=<%
TestUnion(const char* ch); I83ZN]
TestUnion(long l); #/Y t4n
operator const char*() const {return data_.ch_;} AF g*
operator long() const {return data_.l_;} ~@S5*(&8
}; @%q0fj8b
lR\=] ]7I>
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) HaXlc8
{//注意data_(ch),这里直接引用data_ >:!TfuU^R
} 8zS't2
u
AdxCP\S&
TestUnion::TestUnion(long l):data_(l),stype_(Long) !([Q1r{u
{//注意data_(l),这里直接引用data_ br*L|s\P\9
} JhRXfIK>{
)sWdN(E3
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) oM/(&"
{
#"&h'V
} 8;mn7 XX
*lRP ZN
TestUnion::DataUnion::DataUnion(long l):l_(l) /Y_F"GQ
{ L']EYK5
} dPwe.:
3
[: x#r
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!