前言 5J1,Usm
I)n%aT fo8
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 l? 7D0
d)9=hp;,V
一、在union中存储对象 o2&mhT
'Kc;~a
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ~kF^0-JZY
\iO
,y:
#pragma warning(disable : 4786)
rfoLg
#include @#;~_?$?C
using namespace std; = q;ACW,z
$FS
j^v]
class TestUnion ys09W+B7
{ ~
M@8O
public: T+Du/ERL
TestUnion(long l):data_(l) *<]ulR2
{ Fb.wm
}; F d *p3a
int data_; k${25*M!3
}; {ge^&l
O &;Cca
typedef union _tagUtype_ ,D;d#fJ
{ +>Y2luR1
TestUnion obj; X`#vH8
}UT; REc69Y.k
-PoW56
int main (void) _-^a8F>/19
{ eY;XF.mF
return 0; t 8|i>(O
} D8G5,s-.
lfK sqe"
3hGYNlQ^
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: (jtrQob
<Y9e n!3\
class TestUnion GK~uoz:^O
{ t#=W'HyW8
public: |!,;IoZ
int data_; 1F{c5
}; X8"4)IZ3
Z`T]jm-3
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! 2old})CLJ
^e1@o\]
二、类中union的初始化 ;y/&p d+
cY0NQKUk~
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: 2.qEy6
+9<"Y6
#pragma warning(disable : 4786) $mgW|TBXCQ
#include mA@FJK_
?^n),mR
using namespace std;
6g576
+<a-;e{
class TestUnion _<qe= hie!
{ #~BsI/m
enum StoreType{Long,Const_CharP}; =+DfIO
union #p*D.We
{ +DU^"q=
const char* ch_; [0qe ?aI
long l_; i}[cq_wJ
} data_; )[+82~F
StoreType stype_; gF#HNv
TestUnion(TestUnion&); Py y!B
TestUnion& operator=(const TestUnion&); 3K!(/,`
public: S6Y2(qdP
TestUnion(const char* ch); |Bz1u|uc
TestUnion(long l); [;t-XC?[nk
operator const char*() const {return data_.ch_;} -Aaim`06bv
operator long() const {return data_.l_;} vhIZkz!9
}; m Q4(<,F
~t^
Umx"Ew
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) FUzN}"\1
{ t-B5,,`
} ~@ =(#tO.
}IEwGoDwNs
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) =h0vdi%{
{ %;_94!(hC
} 0$JH5RC
^F,sV*
int main (void) B\S}*IE
{ B>.x@(}V~
TestUnion pszobj("yuankai"); |W_;L6)
TestUnion lobj(1234); V^Y'!w\LGI
cout<(pszobj)< cout< 2[j(C
return 0; BX\/Am11
} ~I6N6T Z
6~c#G{kc
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: ,_iq$I;
iR?}^|]
class TestUnion !6!Gx:
{ cX7 O*5C
enum StoreType{Long,Const_CharP}; }D># AFs6#
union DataUnion //不能匿名 @@JyCUd
{ *:bexD H
DataUnion(const char*); //声明const char*构造函数 0vX4v)-^u
DataUnion(long); //声明long构造函数 plL|Ubn
const char* ch_;
J-#V_TzJ?
long l_; "i#aII+T
} data_; &S,_Z/BS;
StoreType stype_; Y<L35
?
TestUnion(TestUnion&); L4,b ThSG
TestUnion& operator=(const TestUnion&); HS[($
public: Q2/65$nW
TestUnion(const char* ch); !iO2yp
TestUnion(long l); $Nd,6w*`
operator const char*() const {return data_.ch_;} <O5WY37"q
operator long() const {return data_.l_;} sSd/\Ap
}; d~1uK-L]*
rk6K0TQ8
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) nr2 Q[9~
{//注意data_(ch),这里直接引用data_ _Jy7` 4B.
} F~q(@.b
N=AHS
TestUnion::TestUnion(long l):data_(l),stype_(Long) Kv<f<>|L
{//注意data_(l),这里直接引用data_ F+"_]
} }}"pQ!Z
h PL]B_<
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) }R`Rqg-W
{ |lt]9>|
} ],_+J*
)/?H]o$NU
TestUnion::DataUnion::DataUnion(long l):l_(l) d]poUN~x
{ h5SJVa
} dgL>7X=7
D/?Ec\t
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!