前言 TP#Ncqh
pBe1:
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 %' WC7s
VfzyBjQ
一、在union中存储对象 ;R0LJApey
EoutB Vm
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? [nHN@p|
>dK0&+A
#pragma warning(disable : 4786) e+!xy&u@u
#include (L4llZ;q
using namespace std; rF[-4t
%
r&xIVFPI[
class TestUnion #tg\
bb
{ C+t3a@&|
public: g~-IT&O
TestUnion(long l):data_(l) #f(tzPD
{ L44|/~
}; <;#gcF[7>
int data_; G0h&0e{w
}; >A@yF?
vbJdhaf
typedef union _tagUtype_ XSof{:V
{ ,5<AV K-#Q
TestUnion obj; =LIb0TZ2
}UT; eb}XooX
%cDGs^lgA
int main (void) .n_Z0&i/w
{ -}4CY\d6'
return 0; mEYfsO
} cg^~P-i@*
:I"22EH
=/j!S|P
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: OH`zeI,[*
Chl^LEN:
class TestUnion 1F>8#+B/W
{ VWt=9D;
public: n&&C(#mBC
int data_; #l+Rs3T:
}; }s?w-u+(c6
m["e7>9G
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! fzVN;h
/+B6oE>8
二、类中union的初始化 Ha]vG@?+
r2tE!gMC
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: =3% GLj
vv)O+xt
#pragma warning(disable : 4786) XySkm2y
#include Tt{X(I} J
~C>;0a;<:
using namespace std; zN5};e}^v
8cvSA&l(D
class TestUnion 4gEw}WiP
{ qp*~|
enum StoreType{Long,Const_CharP}; v1+.-hO
union JXww_e[
{ 1NZpd'$c
const char* ch_; hN0h'JJ[7
long l_; vMX\q
} data_; ?HOnDw.v1
StoreType stype_; {=Ji2k0U'
TestUnion(TestUnion&); 3NZK$d=4
TestUnion& operator=(const TestUnion&); /W
f.Gt9[
public: 4_2oDcdf
TestUnion(const char* ch); !]7b31$M_
TestUnion(long l); (p'/a.bn
operator const char*() const {return data_.ch_;} `'r~3kP*NT
operator long() const {return data_.l_;} uF3{FYM{I
}; -f:PgBj
"g"%7jK
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) ]C+PJ:CC
{ bM_fuy55Op
} xrY >Or
Q;y4yJ$wI
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) j5n"LC+oz
{ L`O7-'`
} 45Zh8 k
./DlHS;
int main (void) Zs0;92WL
{ Kx[+$Qt
TestUnion pszobj("yuankai"); ~z41$~/
TestUnion lobj(1234); .2rpQa/h
cout<(pszobj)< cout< RxPD44jVA
return 0; RvU'8Y?>w
} o9Mr7
OFcP4hDi
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 6_rgRo&
8In~qf
class TestUnion RZqMpW
{ ox.kL
enum StoreType{Long,Const_CharP}; it>l?h7 I
union DataUnion //不能匿名 9&kPcFX B
{ 7FaF]G
DataUnion(const char*); //声明const char*构造函数 XMI5j7CL
DataUnion(long); //声明long构造函数 M0vX9;J
const char* ch_; _\@zq*E
long l_; =kOo(
} data_; p?
VDBAx
StoreType stype_; >wYmx4W>
TestUnion(TestUnion&); x=\W TC
TestUnion& operator=(const TestUnion&); :To{&T
public: Y2ON!Rno
TestUnion(const char* ch); .
Wd0}?}
TestUnion(long l); BP&]t1p
operator const char*() const {return data_.ch_;} "9 vL+Hh
operator long() const {return data_.l_;} I&^hG\D
}; Kj?hcGl[
)*.rl
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Hy'EbQ
{//注意data_(ch),这里直接引用data_ bVZAf
} w&hCt