前言 :4x6dYNU
L@jpid95
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 TaaCl#g$?
3sIdwY)ZS_
一、在union中存储对象 '4D7:
*3OlWnZ?
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? |'u BkL0q
ueg%D+u
#pragma warning(disable : 4786) #T8jHnI
#include 7h2/8YUgQ
using namespace std; m:Rm(ga9
f:y:: z
class TestUnion GT80k]e.
{ B.smQt
public: MRZN4<}9
TestUnion(long l):data_(l) ZsCwNZR
{ Nf2lw]-G4
}; 7xY&7 x(v
int data_; :7X{s4AU6
}; Vq/hk
1|s`z
typedef union _tagUtype_ 0v6Z4Ahpo
{ $ %|b6Gr/&
TestUnion obj; [Jjo H1E@
}UT; Jt0/*^'
H6>t to
int main (void) A>315!d"
{ qsN_EMgbdn
return 0; .W$9nbly
} 4~&X]/_'
;j[gE
ux*G*QZ
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: *a0#PfS[
aIr"!. 4
class TestUnion Sn
7h$
{ j|qdf3^f
public: 9eE
FX7
int data_; A[`c+&
}; ,1-idpnX
x9t%
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ~BgYD)ov
n{qVF#N_
二、类中union的初始化 \}<J>R@
bE=[P}E
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下:
Jk:ZO|'Z
()$m9%x
#pragma warning(disable : 4786) [9}<N2,9z
#include ,J<+Wxz
w@YPG{"j
using namespace std; Q,tjODc6n
#,FXc~ V
class TestUnion aI}htb{m`
{ 4x=sJ%E
enum StoreType{Long,Const_CharP}; ^5>W`vwp
union qI
tbY%
{ R%t|R79I
const char* ch_; sya!VF]`
long l_; Yt_t>
} data_; Lm.N
{NV'
StoreType stype_; ;*U&lT
TestUnion(TestUnion&); V`i (vC(
TestUnion& operator=(const TestUnion&); Zs;c0T">
public: 7TU77
TestUnion(const char* ch); { i4`-w
TestUnion(long l); ,6f6r
operator const char*() const {return data_.ch_;} Se\iMs
operator long() const {return data_.l_;} Q&@<?K9
}; Y{@foIZ
pe).
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) _j{)%%?r
{ 1Mx2%
} Y(ClG*6 ++
*_Ih@f H
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ADP3Nic
{ <]#_&Na
} W'E3_dj+
BvH I}=
int main (void) -- IewW
{ lQt,(@7]
TestUnion pszobj("yuankai"); !:uh? RW
TestUnion lobj(1234); bGwj` lue
cout<(pszobj)< cout< 31%3&B:Ts
return 0; l Dwq[ I]w
} f{\[+>
8{7'w|/;.{
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: ]/%CTD(O
UIZ9"Da
class TestUnion .%\||1F<
{ RaymSh
enum StoreType{Long,Const_CharP}; '^O}`
union DataUnion //不能匿名 G[fg!vig#7
{ _0\wyjjU
DataUnion(const char*); //声明const char*构造函数 #k!;=\FV
DataUnion(long); //声明long构造函数 |="Y3}a
const char* ch_; (9] =;)
long l_; $%ztP
Ta
} data_; B <HD
StoreType stype_; "CFU$~
TestUnion(TestUnion&); /R(
.7 N
TestUnion& operator=(const TestUnion&); -
s{&_]A~
public: |y?W#xb
TestUnion(const char* ch); 1p SEr6
TestUnion(long l); ZLf(m35
operator const char*() const {return data_.ch_;} >{rD3X"d
operator long() const {return data_.l_;} r-[YJzf@P
}; 9):^[Wkx
}Py Z{yS
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Z%SDN"+'g
{//注意data_(ch),这里直接引用data_ ?fpI,WFu
} O31.\ZR2
)o&}i3~Q
TestUnion::TestUnion(long l):data_(l),stype_(Long) C
[8='i26
{//注意data_(l),这里直接引用data_ ? fM_Y
} :0o]#7
Go~3L8
'
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) :/fT8KCwo
{ Ro2!$[P
} =trLL+vGw'
fCv.$5
TestUnion::DataUnion::DataUnion(long l):l_(l) _gCi@uXS3
{ H]M[2C7#N
} nQfSQMg
_Pl5?5eZj
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!