前言 XIl#0-E0X
w7vQ6jkH
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 A.r.tf}:
m2ph8KC
一、在union中存储对象 O(_f&a
:?i,!0#"
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? F*NHy.Y
(/t{z=
#pragma warning(disable : 4786) fWDTP|DV
#include gT,iH.
using namespace std; r]wy-GT
-OKXfN]
class TestUnion U<'z,Px6
{ IA}.{zY~|
public: Kf)$/W4
TestUnion(long l):data_(l) n^l5M^.
{ `q1-yH0~4
}; #sbW^Q'I
int data_; %L-{4Z!"sI
}; w[EEA_\
n-<`Z NMU
typedef union _tagUtype_ T ~p>Ed 9
{ NvpDi&i
TestUnion obj; A v;NQt8ut
}UT; 1 7iw`@
%uo#<Ny/ I
int main (void) c^5fhmlt
{ twa H20
return 0; !!Yf>0u#
} Q2Uk0:M
F>%,}Y~B:
2<V`
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: gxC`Ml
:z|$K^)7Z
class TestUnion <N=ow"rD
{ Z hCjY
public: )_?H BTG
int data_; `H^
H#W
}; j2 >WHh
m]{/5L
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ^lK!tOeO
yC!>7@m
二、类中union的初始化 p-7?S^!l
x'%vL",%
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: 8*uaI7;*
yDpv+6(a
#pragma warning(disable : 4786) t6)R37
#include 1Eryw~,,9i
a<((\c_8G
using namespace std; *;lb<uLv
q'X#F8v
class TestUnion RGY#0 .Z}
{ 5\}QOL
enum StoreType{Long,Const_CharP}; (F:|tiV+
union !wro7ilMB
{ ma`sv<f4-!
const char* ch_; _~*ba+{
long l_; Vu<mOuh
} data_; OSC_-[b-
StoreType stype_; Fg2/rC:_
TestUnion(TestUnion&); cn9=wm\\
TestUnion& operator=(const TestUnion&); E6- ~
public: |I.5]r-EK
TestUnion(const char* ch); GB6(WAmr
TestUnion(long l); -,$:^4
operator const char*() const {return data_.ch_;} oiz]Bd
operator long() const {return data_.l_;} 1 Va@w
}; li}>xDSQ4
*r6v9
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) /5\{(=0
{ P rv=f@
} +bWo{
JNu+e#.Y
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) nyG 5sWMpe
{ ~6OdwGWV
} ~AF'
6"A
1}CJ&
int main (void) u:^9ZQ+
{ j?!/#'
TestUnion pszobj("yuankai"); q+XU Cnv
TestUnion lobj(1234); X8XE_VtP
cout<(pszobj)< cout< 2nSz0 .
return 0; 1flB A,6L
} 6(q8y(.`
fs#9*<]m
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: P;ZVv{mT
j<L!(6B
class TestUnion +#@2,
{ U(<~("ocN
enum StoreType{Long,Const_CharP}; xp"F)6
union DataUnion //不能匿名 H.[(`wi!I
{ pJQ_G`E
DataUnion(const char*); //声明const char*构造函数
w4UJXc
DataUnion(long); //声明long构造函数 u>2opI~m
const char* ch_; yJ8_<A
long l_; 9}d^ll&
} data_; 2o0WS~}5
StoreType stype_; SFqq(K2u
TestUnion(TestUnion&); 9['>$ON
TestUnion& operator=(const TestUnion&); 1Msc:7:L
public: 3gW+|3E
TestUnion(const char* ch); 2(Nf$?U@0
TestUnion(long l); ;^8X(R
operator const char*() const {return data_.ch_;} ,B,0o*qc{K
operator long() const {return data_.l_;} ,u.A[{@py
}; !\q'{x5C
Acb %)Y
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) OX.g~M
ig|
{//注意data_(ch),这里直接引用data_ ?"p.Gy)
} Dh9C9<Ta:
s>ZlW:jY
TestUnion::TestUnion(long l):data_(l),stype_(Long) XeAH.i<
{//注意data_(l),这里直接引用data_ rX|{nb
} W!a'KI'
FOuPj+}F
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 1_)Y{3L
{ |eej}G(,m}
} ^O3p:X4u
|b|bL 7nx
TestUnion::DataUnion::DataUnion(long l):l_(l) U+@rLQ.-
{ *47%|bf`
} +3-f$/po
S$nEflcz
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!