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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 *Oy%($'  
<a2Kc '  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。  ur k@v  
` $[`C/h  
  一、在union中存储对象 [+:KIW<  
r\|"j8  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? TJs@V>,  
@2 SL$0!QA  
#pragma warning(disable : 4786) utw@5  
#include ]8opI\  
using namespace std; q,j` _ R4  
lpefOnO[  
class TestUnion E+eC #!&w  
{ bvo }b-]E  
 public: l`{JxVg  
 TestUnion(long l):data_(l) Oin:5K)4-  
 { +L#):xr  
  }; uTP4r  
 int data_; Y F W0  
}; %W$?*Tm  
6r)qM)97  
typedef union _tagUtype_ JZcW?Or  
{ vu)V:y  
 TestUnion obj; DFqVZ   
}UT; nZUBblRJ)  
>@^j9{\  
int main (void) )W![TIp  
{ .fS1  
 return 0; Lmyw[s\U  
} 1 BVpv7@  
;#?+i`9'q  
_ "[O=h:  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: fehM{)x2:  
2lBu"R6}  
class TestUnion rjT!S1Hs  
{ 4_?*@L1  
 public: j'FBt8P'  
 int data_; TM$`J  
}; 6.GIUM%D  
!rgdOlTR^  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! m2Q#ATLW  
,vUMy&AV  
二、类中union的初始化 n!\&X9%[8  
i52:<< 8a  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: "8`f x  
Z9 tjo1X  
#pragma warning(disable : 4786) KRP)y{~o  
#include Hk;) l3oB  
!8>tT  
using namespace std; F!yejn [  
?gOZY\[ma  
class TestUnion .e%B'  
{ U}<;4Px]7v  
enum StoreType{Long,Const_CharP}; $`/J V?Z  
union qnR{'d  
{ _&6&sp<n  
const char* ch_; !/MHD  
long l_; m.N/g,  
} data_; lO0 PZnW9  
StoreType stype_; Z"G@I= Q(  
TestUnion(TestUnion&); KA$l.6&d  
TestUnion& operator=(const TestUnion&); NFcMh+qnK  
public: Yv jRJ  
TestUnion(const char* ch); bi[gyl#  
TestUnion(long l); lTpmoDa%  
operator const char*() const {return data_.ch_;}  $mG&4Y  
operator long() const {return data_.l_;} /S+gh;2OC  
}; p,+$7f1S  
w">p 8  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) QA&BNG  
{ 8z, |N#  
} ?yt"  
mam2]St"  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) "J%/xj  
{ CzZm C]5  
} 38T2IN  
c B9`U4<  
int main (void) YkLEK|d  
{ \[w82%U  
TestUnion pszobj("yuankai"); B? r[|  
TestUnion lobj(1234); {!hA^[}|  
cout<(pszobj)< cout< Jm8#M z  
return 0; D0=H&Z[  
} P:y M j&)  
u;*Wc9>sU  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: &Rx-zp&dJ  
ISuye2tExq  
class TestUnion +9mnxU>  
{ +LM /< l  
enum StoreType{Long,Const_CharP}; D=nuK25  
union DataUnion //不能匿名 'WG%O7s.  
{ %vO b"K$X  
DataUnion(const char*); //声明const char*构造函数 w;(`!^xv  
DataUnion(long); //声明long构造函数 T7=~l)I  
const char* ch_; agFWye  
long l_; :n&n"`D~  
} data_; 7u Q-:n  
StoreType stype_; NK+iLXC  
TestUnion(TestUnion&); j6KGri  
TestUnion& operator=(const TestUnion&); 6 2r%q^r`i  
public: ;Qc_Tf=,  
TestUnion(const char* ch); =MqefV;-  
TestUnion(long l); T)ra>r<#  
operator const char*() const {return data_.ch_;} T.zU erbO  
operator long() const {return data_.l_;}  %Ln7{w  
}; Y|=/*?o}  
t F<|Eja *  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) q|. X[~e|  
{//注意data_(ch),这里直接引用data_ FU|c[u|z  
} dkC[Jt  
do9@6[{Sv  
TestUnion::TestUnion(long l):data_(l),stype_(Long) {%5tqF  
{//注意data_(l),这里直接引用data_ C{ {DZ*  
} L+PrV y  
;w,g|=RQ  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) f`?Y+nu}  
{ ]kuMzTH  
} L s=2!  
F.b;O :  
TestUnion::DataUnion::DataUnion(long l):l_(l) sSC yjS'T  
{ c"3 a,&  
} fRe$}KX  
0k5;Qf6A  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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