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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 m9*Lo[EXO  
rE?(_LI  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 RG(m:N  
s3m]rC  
  一、在union中存储对象 ?h`Ned0P  
]7WBoC8  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ?3 :OPP`s  
|&IS ZFSv  
#pragma warning(disable : 4786) F|._'i+B!  
#include GH%'YY3|  
using namespace std; Qxds]5WB/  
)tQG5.to  
class TestUnion p%304oP6  
{ ,#^<0u+zrF  
 public: N*t91 X  
 TestUnion(long l):data_(l) Sz0M8fYT]  
 { [BS3y`c  
  }; m35Blg34  
 int data_; A`4Di8'Me  
}; Q(lj &!?1k  
MFHPh8P  
typedef union _tagUtype_ UA4Q9<>~  
{ z-G|EAON"/  
 TestUnion obj;  & y1' J  
}UT; f_1#>]  
L2ePWctq}  
int main (void) !Ju?REH   
{ yHW=,V.  
 return 0; I\R5Cb<p  
} 1jZ:@M :  
rI&GM |  
e_J_rx  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: l*[.  
E-,74B&H  
class TestUnion S=O/W(ZB  
{ RVN"lDGA  
 public: gnbs^K w  
 int data_; .vRLK  
}; &J|3uY,'j  
3j.Ft*SV  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! %h U8ycI*h  
7BCCQsz<  
二、类中union的初始化 /'1UfjW>  
qF6YH  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: D={|&:`L e  
HMNjQ 1y  
#pragma warning(disable : 4786) hCO*gtA)M  
#include 6G"AP~|0  
*BVkviqxz  
using namespace std; iV#JJ-OBq  
sm}q&m]ad  
class TestUnion {+f@7^/i.  
{ uF>I0J#z?  
enum StoreType{Long,Const_CharP}; =SLP}bP{:  
union <FH3 ePz  
{ bG +p  
const char* ch_; '#<?QE!d2  
long l_; x]%e_  
} data_; z Q NL){  
StoreType stype_; ]sO})  
TestUnion(TestUnion&); "}D uAs  
TestUnion& operator=(const TestUnion&); !lE (!d3M  
public: Oa~t&s  
TestUnion(const char* ch); k%QhF]  
TestUnion(long l); 1?HUXN#,  
operator const char*() const {return data_.ch_;} eif<aG5  
operator long() const {return data_.l_;} w5jH#ja  
}; ?mY )m +  
zdn e2  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) P*/px4;6  
{ /s6':~4  
} xkl'Y*  
\Ja%u"D A  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) cWgiFv  
{ TJ`E/=J!  
} xk86?2b{)  
mKZ?H$E%%  
int main (void) EA75 D&>I  
{ _6qf>=qQ`"  
TestUnion pszobj("yuankai"); BW:&AP@B  
TestUnion lobj(1234); 8E/$nRfO d  
cout<(pszobj)< cout< AEK* w4  
return 0; [8Ub#<]]  
} [w~teX0!  
N;D (_:^  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: OM]p"Jd  
{AIP\  
class TestUnion <(d ^2-0  
{ 1*?IDYB  
enum StoreType{Long,Const_CharP}; XPzwT2_E  
union DataUnion //不能匿名 =,-80WNsX  
{ ".v9#|  
DataUnion(const char*); //声明const char*构造函数 e`R*6^e  
DataUnion(long); //声明long构造函数 i>T{s-3v  
const char* ch_; +n9&q#ah  
long l_; ^/R@bp#<  
} data_; -'{ioHt&X/  
StoreType stype_; jD_(im5  
TestUnion(TestUnion&); 3Q[]lFJ}F  
TestUnion& operator=(const TestUnion&); ix^:qw;  
public: Rjo6Pd{d<  
TestUnion(const char* ch); qChS} Q  
TestUnion(long l); :<ujk  
operator const char*() const {return data_.ch_;} B/E1nBobC  
operator long() const {return data_.l_;} *~4uF  
}; F.?:Gd1  
`]WU=Ss  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) wias ]u|  
{//注意data_(ch),这里直接引用data_ VjYfnvE  
} <3HW!7Ad1  
zDa*n:S  
TestUnion::TestUnion(long l):data_(l),stype_(Long) CJjma=XH  
{//注意data_(l),这里直接引用data_ \EYhAx`2  
} &z{oVU+mA  
p(nC9NGB  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) ZH_ J+  
{ GOH@|2N  
} dSIMwu6u  
kp<9o!?)  
TestUnion::DataUnion::DataUnion(long l):l_(l) (U!WD`Ym  
{ E_WiQ?p   
} Js^ADUy  
}E8 Y,;fTD  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
如果您在写长篇帖子又不马上发表,建议存为草稿
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八