前言 E.9k%%X]
Rj=Om
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 )S?}huX
H.K`#W&
一、在union中存储对象 w+P^c|
F\72^,0
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? I ^92b
IbwRb
#pragma warning(disable : 4786) - mXr6R?
#include {mGWMv
using namespace std; n/D]r
}Cf[nGh|B
class TestUnion M lwQ_5O
{ !-~(*tn
public: [GM<Wt0
TestUnion(long l):data_(l) ^q2zqC
{ Fowh3go
}; A[a+,TN{
int data_; pBLO
}; ??Ac=K\
7^5BnF@
typedef union _tagUtype_ ;O>fy:$'
{ lNAHn<ht
TestUnion obj; WQ`T'k#ESW
}UT; i(rY'o2 BN
KR0
x[#.*
int main (void) %Ski5q
{ L\DaZ(Y
return 0; < Ifnf6~
} {*Pp^r
![%,pip2/&
b"9,DQB=i
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: }FVX5/.'
h65j,v6B
class TestUnion rg.if"o
{ eRbO Hj1
public: k*^W
lCZ3
int data_; O ?Tg`] EX
}; ?Y* PVx9Y
YZ@-0_Z
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! 2=EKAg=S
[%kucG C7
二、类中union的初始化 :_ox8xS4
lsCh K
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: ,pzCJ@5
*Cw2 h
#pragma warning(disable : 4786) xkovoTzV
#include F)Lbr>H?I
sd%~pY}
using namespace std; 7/L7L5h<
*_wBV
M=2
class TestUnion :_*Q
IyW
{ 4fswx@l
enum StoreType{Long,Const_CharP}; `m^OnH
union qZe"'"3M
{ VWa(@A
const char* ch_; Y{=@^4|]
long l_; /+msrrpD
} data_; |e\%pfZ
StoreType stype_; Lw`\J|%p
TestUnion(TestUnion&); ej+!|97M
TestUnion& operator=(const TestUnion&); 3I+pe;
public: J7xmf,76w
TestUnion(const char* ch); 1S.~-K*X
TestUnion(long l); .2xkf@OP
operator const char*() const {return data_.ch_;}
2X_ef
operator long() const {return data_.l_;} ZI7<E
}; )RFeF!("
c^y 1s*
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) _rd{cvdR
{ xJCpWU3wM
} xTT>3Fj
CCV~nf
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) Rd)QVEk>SD
{ tUQ)q
} d/1XL[&
s9iM hCu|
int main (void) S J5kA`
{
s25012
TestUnion pszobj("yuankai"); |+;"^<T)l
TestUnion lobj(1234); nP^$p C
cout<(pszobj)< cout< HdM;c*K
return 0; tANG ]
} /
<p HDY
eORt
qX8*
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: jTnu! H2o
/7^~*
class TestUnion -bwl~3ZTi
{ OjZ@_V:
enum StoreType{Long,Const_CharP}; PW}.`
union DataUnion //不能匿名 Cp%|Q.?
{ PBmt.yF
DataUnion(const char*); //声明const char*构造函数 &,zeBFmc
DataUnion(long); //声明long构造函数 rzu^br9X
const char* ch_; ;QYK {3R?
long l_; z( wXs&z;
} data_; \"SI-`x
StoreType stype_; w8qI7/
TestUnion(TestUnion&); y.zQ `
TestUnion& operator=(const TestUnion&); :Lx]`dSk
public: 4tI~d8?pk+
TestUnion(const char* ch); K_i2%t3
TestUnion(long l); =R05H2hs
operator const char*() const {return data_.ch_;} jKzjTn9{E
operator long() const {return data_.l_;} \1ZfSc
}; qb Q> z+c
x+pFu5,
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Ero3A'f
{//注意data_(ch),这里直接引用data_ wrbDbp1L
} (rJvE*
O%r<I*T^r
TestUnion::TestUnion(long l):data_(l),stype_(Long) >KE(%9y~
{//注意data_(l),这里直接引用data_ LdOB[W
} Dng^4VRd
iaB5t<t1r
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) GOt@x9%
{ t.cplJF&Ue
} _3hEYeh
EO5Vg
TestUnion::DataUnion::DataUnion(long l):l_(l) gP3[=a"\
{ )Ii=8etdv
} ?Rdi"{.wI
o! 8X< o
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!