前言 ^NCH)zK]v
<O*q;&9
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 dfrq8n]
qV}zV\Nz
一、在union中存储对象 fT@#S}t
%d>Ktf
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? D"o>\Q
"<&F=gV
#pragma warning(disable : 4786) 5P! ZJ3C
#include k/LV=e7
using namespace std; cVz.ac
-1{N#c/U
class TestUnion Mz06cw&
{ D( _aXy
public: p7k0pSt
TestUnion(long l):data_(l) @wg*~"d
{ Y,8M[UIK
}; $HH(8NoL
int data_; *s!8BwiE
}; >S~ #E,Tg
"#9WF}
typedef union _tagUtype_ WOwIJrP
{ lf Giw^
TestUnion obj; 3!d|K%J
}UT; We9mkwK7C
fEpY3od
int main (void) ja:%j&:
{ 1{,WY(,c
return 0; Mpj3<vj
} ~@-Az([H
A$
S9
`
7' 6m;b~F
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: Og,,s{\
U,]z)1#X|
class TestUnion
+Q'/c0o
{ ,og@}gOMB
public: |S4yol
int data_; 3v {GP>
}; n,0}K+}
5!5P\o
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ou(9Qf zN
k}BNFv8
二、类中union的初始化 lP@9%L
9M7{.XR,
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: g<,|Q5bK
ZSbD4
|_
#pragma warning(disable : 4786) TX*P*-'
#include 8n'C@#{WV
iWvgCm4
using namespace std; H,uOshR
rbJ-vEzo.#
class TestUnion l&C%oW
{ O}D]G%,m
enum StoreType{Long,Const_CharP}; _h.[I8xgYG
union eLt6Hg)s`9
{ 1LE8,Gm&
const char* ch_; W9u(
long l_; #ucOjdquq
} data_; SKYS6b
StoreType stype_; GWhb@K
TestUnion(TestUnion&); S</"^C51J
TestUnion& operator=(const TestUnion&); F\XzP\
public: U%KoG-#
TestUnion(const char* ch); 8gx^e./
TestUnion(long l); `j<'*v
zo
operator const char*() const {return data_.ch_;} ?5->F/f&
operator long() const {return data_.l_;} )ei+ewVZ
}; *|4~
0w
K_My4>~Il
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) 7tyn?t0n
{ nVYh1@yLy
} G q:7d]c~T
)`U T#5
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) pZWp2hj{X
{ .AV--oA~
} Tn-H8;Hg
3FS:]|oC
int main (void) }we"IqLb
{ !867DX3*
TestUnion pszobj("yuankai"); @@I2bHyvb
TestUnion lobj(1234); *M8 4Dry`y
cout<(pszobj)< cout< PCFm@S@Q
return 0; `yxk
Sb
} }b0qrr
%fxGdzu7.
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: hup]Jk
PS6G 7
class TestUnion paF2{C)4
{ vF*H5\ m<a
enum StoreType{Long,Const_CharP}; {)Gh~~57_W
union DataUnion //不能匿名 \(Hg_]>m
{ tBf u{oC
DataUnion(const char*); //声明const char*构造函数 CqF<
BE
DataUnion(long); //声明long构造函数 ]r#tJT`M
const char* ch_; sGzd c
long l_; K{0mb
} data_; ))+R*k%
StoreType stype_; inhb> zB
TestUnion(TestUnion&); TX 12$p\
TestUnion& operator=(const TestUnion&); zS?L3*u
public: m@yaF:
R
TestUnion(const char* ch); K J~f ~2;
TestUnion(long l); kiXa2Yn*(d
operator const char*() const {return data_.ch_;} Bg34YmZ
operator long() const {return data_.l_;} 1ra}^H}
}; HM<V$
R
bbnAF*7s8
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) AA@J~qd
u
{//注意data_(ch),这里直接引用data_ TeG'cKz
} =b;v:HC
rb9x||
TestUnion::TestUnion(long l):data_(l),stype_(Long) 2Ejs{KUj
{//注意data_(l),这里直接引用data_ MEo+S
} 0$P40 7
id*UTY
Tg
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) :yO)g]KF
{ *WOA",gZ
} _tYt<oB~%
Gd"lB*^Ht
TestUnion::DataUnion::DataUnion(long l):l_(l) (?~F}u
v
{ eyy&JjVs
} _~6AUwM
in%+)`'nH7
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!