前言 hhN(;.
tsCz+MP
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 :7zI3Ml@7
EU`'
8*4
一、在union中存储对象 c80"8r
J@=!w[v+
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? s|Imz<IE
bcGn8
#pragma warning(disable : 4786) p\4h$."
#include Pl`Bd0
using namespace std; A- <.#
WV9[DFU
class TestUnion t!+%g) @
{ {&6l\|
public: [346w
<
TestUnion(long l):data_(l) Th I
{ $D0)j(v
}; 0B#rqTEKu
int data_; ?STI8AdO
}; RXCygPT
<"j"h=tm}
typedef union _tagUtype_ _dH[STT
{ |\yDgs%EGy
TestUnion obj; [kU[}FT
}UT; gwkZk-f\p
S1 R #]
int main (void) g[uE@Gaj&
{ x<)!$cg
return 0; ?CL z@u~
} "N=&4<]I5
:6HiP&<
z^SN#v$
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: Au\=ypK
{d{WMq$
class TestUnion am)J'i,
{ j$JV(fz
public: G5X|JTzpu<
int data_; :Kt mSY
}; }J4BxBuV8
1bFEx_
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Hf`&&
l.Lc]ZpB
二、类中union的初始化 tL|L"t_5x
~h~r]tV*+
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: ZFd{q)qe
`rRg(fCN!M
#pragma warning(disable : 4786) g]TI8&tP!L
#include fitK2d
[jmAMF<F
using namespace std; hPX2 Bp
! a8h
class TestUnion Av[|.~g
{ LOYyj?^7
enum StoreType{Long,Const_CharP};
e>s.mH6A
union ^AC+nko*
{ NJz*N%VWD
const char* ch_; ;Ef)7GE@\[
long l_; P St|!GST
} data_; A&@jA5Jb
StoreType stype_; Q'V,?#
TestUnion(TestUnion&); m'vOFP)'
TestUnion& operator=(const TestUnion&); I$sm5oL
public: EXScqGa]
TestUnion(const char* ch); G5Dji_ |
TestUnion(long l); ,4?|}xg
operator const char*() const {return data_.ch_;} hJL0M!
operator long() const {return data_.l_;} u8)r
W
}; ;z=C^'
:8/M6-EK
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) OW5|oG
{ d+wNGN
} R;I-IZS:
$DMu~wwfG
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) l2_E6U"
{ 5&7?0h+I
} RM=+ZmA
"NI>HO.U
int main (void) d4rJ?qw
{ ^a0-5
TestUnion pszobj("yuankai"); OA5md9P;d
TestUnion lobj(1234); T;vPR,]rz
cout<(pszobj)< cout< &JzF
return 0; &-.eu
} MyS7AL
'c\TMb.
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: b|C,b"$N0
XdXS^QA.s
class TestUnion "7u"d4h-:(
{ H@bmLq
enum StoreType{Long,Const_CharP}; TuhL:
union DataUnion //不能匿名 n"VE!`B
{ ;@UX7NA
DataUnion(const char*); //声明const char*构造函数 _-2n3py
DataUnion(long); //声明long构造函数 nJ`a1L{N
const char* ch_; Yka yT0!
long l_; <EE+
S#z
} data_; InGbV+ I
StoreType stype_; lbXkZ ,
TestUnion(TestUnion&); Z.#glmw^=R
TestUnion& operator=(const TestUnion&); G"R>a w
public: `x^,k%
:4
TestUnion(const char* ch); 6xQe!d3>s3
TestUnion(long l); fP4IOlHkE
operator const char*() const {return data_.ch_;} t
1'or
operator long() const {return data_.l_;} $@!&ML
}; ?^A:~" ~
dg@/HLZ
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) :a<TV9?H0
{//注意data_(ch),这里直接引用data_ %>}7$Y%
} Z["nY&.sI
>]N0w
TestUnion::TestUnion(long l):data_(l),stype_(Long) i!-sbwd7
{//注意data_(l),这里直接引用data_ ,Onm!LI=
} SNV+.xN
gKH"f%lK
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) GHrT?zEX
{ ,oVBgCf
} S:T>oFUot
n`2"(7Wj
TestUnion::DataUnion::DataUnion(long l):l_(l) 5/VB'N#7s
{ :jp$X|
}
"S} hcAL/
+mF 2yh
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!