社区应用 最新帖子 精华区 社区服务 会员列表 统计排行 社区论坛任务 迷你宠物
  • 5106阅读
  • 0回复

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 -zTeIvcy5  
(p2a{v}fEz  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 )i>KYg w  
O0I/^  
  一、在union中存储对象 DuFlN1Z  
FJ[(dGKeE  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? {M$8V~8D  
z DK+8  
#pragma warning(disable : 4786) 9(I4x]`  
#include l-npz)EM  
using namespace std; }$UFc1He\J  
SVHtv0Nx  
class TestUnion BdYh:  
{ X3>(K1  
 public: ~& l`"  
 TestUnion(long l):data_(l) .KD07  
 { f ;Dz(~ hw  
  }; 5Tu.2.)N  
 int data_; xphqgOc12,  
}; &V ;a:  
dvf*w:5K!  
typedef union _tagUtype_ 5SjS~ 9  
{ -Z@ p   
 TestUnion obj; "&ks8 3  
}UT; *SW,pHYnLb  
i>~?XVU  
int main (void) Ob6vg^#  
{ wVVe L$28  
 return 0; K$Ph$P@   
} WAEKvM4*i0  
Y `{U45  
+EB# #  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: pA2U+Q@  
PX'LN  
class TestUnion 'tbb"MEi4  
{ @.{  
 public: u%pief  
 int data_; = `^jz}  
}; (g Z!o_  
D)_Ei'+*l  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! piP8ObGjy  
s :ruCS  
二、类中union的初始化  g{%';  
qj1z>,\  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: -: ,h8JyMP  
(Ka# 6   
#pragma warning(disable : 4786) coWBKWF  
#include Y[!a82MTzn  
C gx?K]>y  
using namespace std;  xYT.J 6  
kslN_\   
class TestUnion \p$0  
{ D}T, z  
enum StoreType{Long,Const_CharP}; {UcIt LjY  
union ng*%1;P  
{ o$O,#^  
const char* ch_; Bu1z$#AC  
long l_; F(<8:`N;G  
} data_; +a/o)C{  
StoreType stype_; o(P:f)B  
TestUnion(TestUnion&); Nj0)/)<r+  
TestUnion& operator=(const TestUnion&); x/=j$oA  
public: vNC0M:p,  
TestUnion(const char* ch); [R4x[36Zp  
TestUnion(long l);  qR qy  
operator const char*() const {return data_.ch_;} blcKtrYg  
operator long() const {return data_.l_;} lQBM0|n  
}; ~t={ \,X\  
iI*7WO[W  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) Jdn*?hc+  
{ d 4]%Wdvf  
} $]kg_l)  
KIo}Gd&  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ^d80\PXz  
{ :eW~nI.Vc  
} hli 10p$  
#-T.@a1X  
int main (void) /BM1AV{s6  
{ Nz*sD^SJa  
TestUnion pszobj("yuankai"); |Vi&f5p,@  
TestUnion lobj(1234); n#Roz5/U  
cout<(pszobj)< cout< (:QQ7xc{}  
return 0; n*Vd<m;w  
} +5[oY,^cO  
-kbm$~P  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: }4SSo)Uv/  
Y/H^*1  
class TestUnion xXZKj  
{ pFTlhj)1  
enum StoreType{Long,Const_CharP}; s&hA  
union DataUnion //不能匿名 S |>$0P4W(  
{  7E`(8i  
DataUnion(const char*); //声明const char*构造函数 hFMst%:y$  
DataUnion(long); //声明long构造函数 5lnSa+_/f  
const char* ch_; ulf/C%t,R  
long l_; <z uE=0P~%  
} data_; ex \W]5  
StoreType stype_; H@E" )@92  
TestUnion(TestUnion&); _}OJPahw  
TestUnion& operator=(const TestUnion&); GQ2PmnV +  
public: q 9S z7_K  
TestUnion(const char* ch); .vS6_  
TestUnion(long l); Reu{   
operator const char*() const {return data_.ch_;} b$O_L4CP  
operator long() const {return data_.l_;} 9K':Fn2,  
}; lt6;*z[  
UZP6x2:=  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) _i[)$EgFm  
{//注意data_(ch),这里直接引用data_ 2BDan^:-Av  
} DBJA}Cw  
lVdT^"~3  
TestUnion::TestUnion(long l):data_(l),stype_(Long) M~Qj'VVL  
{//注意data_(l),这里直接引用data_ |90 +)/$4  
} BD7@Mj*|  
mO)PJd2ZD  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) t*d >eK`:N  
{ GrR0RwnH)?  
} tx5T^K7[  
oNB,.:  
TestUnion::DataUnion::DataUnion(long l):l_(l) ?[VpN2*  
{ 8i;)|z7  
} yW^IN8fm  
{R-82%X  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
温馨提示:欢迎交流讨论,请勿纯表情、纯引用!
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八