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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 sY1*Wo lA  
3-_4p8OK  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 $]%k <|X  
b!UT<:o  
  一、在union中存储对象 W6jB!W  
lUWjm%|  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? Q>z0?%B  
B"{CWH O  
#pragma warning(disable : 4786) %`g qV9a  
#include a_Xh(d$  
using namespace std; KXdls(ROP  
12k)Ek9  
class TestUnion -pLb%f0?  
{ j&#p&`B  
 public: 4V[+6EV  
 TestUnion(long l):data_(l) sb8SG_c.  
 { K,^b=_]  
  }; I@x*>  
 int data_; xi|iV1A  
}; I *}:C  
w#"c5w~  
typedef union _tagUtype_ [% 3{mAd  
{ G.(9I~!  
 TestUnion obj; i2swots  
}UT; h3JIiwv0!  
`Y+p7*Qr2  
int main (void) eJ?SLMLY  
{ eQYW>z'%,  
 return 0; XFM6.ye  
} a:P% r  
C0kwI*)  
\WZ00Y,*  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: p%,JWZ[  
HK ;C*;vC%  
class TestUnion >r{,$)H0  
{ sy]1Ba%  
 public: KXR  
 int data_; hS<x+|'l  
}; 9-L.?LG  
$r_z""eOc  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! `cVG_= 2  
|@Z QoH  
二、类中union的初始化 H,zRmK6A%  
\7Zk[)!FL  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: i;Gl-b\_h  
dyg1.n#M}  
#pragma warning(disable : 4786) Ba@UX(t  
#include z+wBZn{0I  
(+T|B E3*#  
using namespace std; 4?d2#Xhs8  
G =lC[i  
class TestUnion |n* I}w^  
{ b/<n:*$   
enum StoreType{Long,Const_CharP}; I,q3J1K  
union -+c_TJ.dC  
{ *jDzh;H!w  
const char* ch_; >5XE*9  
long l_; <;_X=s`f,  
} data_; 9/Q5(P  
StoreType stype_; QvqX3FU  
TestUnion(TestUnion&); v`no dI  
TestUnion& operator=(const TestUnion&); T#h`BtET[  
public: "9R3S[  
TestUnion(const char* ch); UG1^G07s  
TestUnion(long l); u*PN1E  
operator const char*() const {return data_.ch_;} n {^D_S  
operator long() const {return data_.l_;} ;2& (]1X  
}; o2Z# 5-  
 E#ti  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) X;zy1ZH  
{ }X}fX#[  
} ?;}2 Z)  
M|76,2u   
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) =X>?Y,   
{ BcA:M\dK%  
} "z7.i{  
<!4'?K-N  
int main (void) C;STJrew  
{ `) K1[&  
TestUnion pszobj("yuankai"); ?$8OVq.w,  
TestUnion lobj(1234); K{"(|~=U  
cout<(pszobj)< cout< .7cQKdvcC  
return 0; Rz%+E0  
} 'N'EC`R  
Z?1.Y7Npr  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: -YRF^72+  
C3WqUf<8`{  
class TestUnion kjjO<x?&*  
{ IDwneFO  
enum StoreType{Long,Const_CharP}; QiB:K Pz[  
union DataUnion //不能匿名 Z\`uI+`  
{ 6(X(f;MEl  
DataUnion(const char*); //声明const char*构造函数 %'@&j2j>  
DataUnion(long); //声明long构造函数 e|xRK?aVBu  
const char* ch_; H?^Poe(=(  
long l_; M(SH3~  
} data_; +*F ;l\R  
StoreType stype_; m<TKy_C`  
TestUnion(TestUnion&); eV}Ow`~I5  
TestUnion& operator=(const TestUnion&); ,zz+s[ZH7O  
public: '6[0NuB  
TestUnion(const char* ch); r1$ O<3\  
TestUnion(long l); >a@-OJ.yOk  
operator const char*() const {return data_.ch_;} )1&[uE#L  
operator long() const {return data_.l_;} ;v>2z!M  
}; B!rY\ ?W  
_fa2ntuS=f  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) +>37 'PD  
{//注意data_(ch),这里直接引用data_ $Jx] FZDQ  
} :\gdQG  
;h3c+7u1  
TestUnion::TestUnion(long l):data_(l),stype_(Long) & P,8 )YA  
{//注意data_(l),这里直接引用data_ =d&  
} ANi}q9SC  
mI9~\k&9  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) ~#7=gI&p@  
{ oM Q+=  
} *|ubH?71%Y  
;S2^f;q~$  
TestUnion::DataUnion::DataUnion(long l):l_(l) B0nkHm.Sj  
{ Ws.F=kS>h  
} dk-Y!RfNx  
&F)P3=  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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