前言 MZP><Je&
%oCjZ"ke
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 0)`lx9&h
Y"/UYxCm|&
一、在union中存储对象 ,@>rubUz
[A..<[
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 6P*)rye
j3[OY
#pragma warning(disable : 4786) ^? {kj{v
#include <]e;tF)+
using namespace std; ;~Gpw/]5E
zs&`:
class TestUnion >'|xQjLl
{ FTYLMQ
i
public: +#JhhW
Zj(
TestUnion(long l):data_(l) q' V{vFfY%
{ 8rG&CxI
}; T4}?w
int data_; np\Q&
}; ; ?lM|kK
qM:)daS1w
typedef union _tagUtype_ oJ@PJvmR&a
{ 'lRHdD}s
TestUnion obj; [ 6o:v8&3
}UT; ty< tv|p
OYtus7q<
int main (void) h7]]F{r5
{ MW[ 4^
return 0; P[P72WR
} U}wq~fD
t02"v4_i
,sJfMY
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: 5GFnfc}
8kc'|F\
class TestUnion 0(g MR
{ ^$,kTU'=
public: BG8)bhk;/
int data_; IC-xCzR
}; 8Bt-
}7z+
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Xsn - +e
f-nC+
二、类中union的初始化 l(#Y8
7%}3Ghc%
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: LXF%~^^@d
99>yaW
#pragma warning(disable : 4786) Jc?ssm\%
#include rtF6Lg
nkj'AH"2
using namespace std; molowPI
`6sQlCOnF
class TestUnion _r|ytQ)
{ <T/L.>p4
enum StoreType{Long,Const_CharP}; |#jm=rT0y
union "#k(V=y
{ GXK?7S0H
const char* ch_;
q8bS@\i
long l_; GWZXRUc
} data_; J<* Mk
StoreType stype_; 0a%ui2k
TestUnion(TestUnion&); hGXDu;{
TestUnion& operator=(const TestUnion&); }UdqX1jz
public: CPeK0(7Zh
TestUnion(const char* ch); fDHISJv
TestUnion(long l); 3&Rqz9 W
operator const char*() const {return data_.ch_;} jeFl+K'1
operator long() const {return data_.l_;} ~ A|*]0,
}; 1O7ss_E
3A}8?
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) T2; 9
{ "FIx^
} &.4_4"l(
2`U&,,-Mf
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) -XG$ 0
{ ]~Qk g+>'&
} [te7uZv-
EoCwS
int main (void) w>Sz^_ h
{ \^LR5S&
TestUnion pszobj("yuankai"); R_&z2I
TestUnion lobj(1234); Q^w]Nj(e_
cout<(pszobj)< cout< Cjk AQ(9
return 0; EC#10.
} FRk_xxe"K
o:\a
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: ]m>MB )9
+[[gU;U"v
class TestUnion DP]|}8~L
{ MA6%g} o
enum StoreType{Long,Const_CharP}; vJUB; hD
union DataUnion //不能匿名 C8q-gP[
{ hI{Yg$H1
DataUnion(const char*); //声明const char*构造函数 |c/rHEZ
DataUnion(long); //声明long构造函数 q~_jF$9SX
const char* ch_; M0
8Y
long l_; Wh_c<E}&
} data_; h8Si,W3o
StoreType stype_; BZshTP[`
TestUnion(TestUnion&); `VN<6o(
TestUnion& operator=(const TestUnion&); iW~f
public: 9V\`{(R
TestUnion(const char* ch); P@?CQvMx
TestUnion(long l); .r'.5RI A
operator const char*() const {return data_.ch_;} T9?_ `h
operator long() const {return data_.l_;} 0u\@-np
}; ^%JWc 3jZ
^umAfk5r?H
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) gHshG;z*
{//注意data_(ch),这里直接引用data_ [?*^&[
}
GXVGU-br
?,C,q5
T\
TestUnion::TestUnion(long l):data_(l),stype_(Long) R FiR)G ,
{//注意data_(l),这里直接引用data_ r+u\jZ
} blv6
+Ti@M1A&
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) -wRzMT19MG
{ Yl])Q|2I
} cTp+M L
^XVa!s,d
TestUnion::DataUnion::DataUnion(long l):l_(l) _Tz!~z
{ ERjf.7)d
} c 3dZ1v
lUd,-
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!