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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 e,k2vp!<&  
yMc:n "-[  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 G~wFnl%  
3Wcy)y>2Ap  
  一、在union中存储对象 8ZcU[8r  
J9%@VZut  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? <&pKc6+{  
&[a Tw{2  
#pragma warning(disable : 4786) D -IR!js ]  
#include ~:lKS;PRuK  
using namespace std; o5Y2vmz?9  
F52B~@ .  
class TestUnion _Mc>W0'5@  
{ "BVdPSDBk  
 public: xM s]Hs  
 TestUnion(long l):data_(l) /u`3VOn  
 { WlV z,t'if  
  }; F?u^"}%Fc  
 int data_; y^Vw`-e  
}; 1ndJ+H0H  
w %c  
typedef union _tagUtype_ W3&tJ8*3  
{ 'P laMOy  
 TestUnion obj; 4'Xgk8)  
}UT; C;Ic  
7OVbP%n)d2  
int main (void) I,ci >/+b  
{ _2hXa!yO  
 return 0; ,WWj-X|+=  
} ]lS@}W\  
Q0_>'sEM  
Ybg- "w  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: yPu4T6Vv  
( 0Naf  
class TestUnion J?n<ydZSH  
{ Zt@Z=r:&  
 public: Gzt=u"FV  
 int data_; ;\y ;  
}; b!$}ma;B  
kw,$NK'  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! /.V0ag'G  
#\4 b:dv  
二、类中union的初始化 ~^N]y b  
uH\kQ9f  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: ?mRE'#  
},+~F8B  
#pragma warning(disable : 4786) #T~&]|{,  
#include F9XT lA  
!:fv>FEI9  
using namespace std; NvtM3  
Omag)U)IPh  
class TestUnion {.k)2{  
{ 7;LO2<|1  
enum StoreType{Long,Const_CharP}; h<p3'  
union v })Q  
{ |G=[5e^s[  
const char* ch_; GlR~%q-jiQ  
long l_; rUwE?Ekn/  
} data_; o*ANi;1]&B  
StoreType stype_; 6ri#Lw  
TestUnion(TestUnion&); 8 #oR/Nt  
TestUnion& operator=(const TestUnion&); ?\H.S9CZ^  
public: $zkH|] zZ  
TestUnion(const char* ch); Erb Sl  
TestUnion(long l); ,#'7)M D8  
operator const char*() const {return data_.ch_;} 8*!|8 BPj^  
operator long() const {return data_.l_;} R[A5JQ$[  
}; _MYx%Z  
;?IT)sNY  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) `Y3(~~YGn  
{ }qC SS<a  
} H3 m8  
3vJ12=  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) }X$l\pm  
{ $W!]fcZlB  
} . %(^mK)zQ  
<9@7,2  
int main (void) S2=%x.  
{ MV+i{]  
TestUnion pszobj("yuankai"); 3;$bS<>  
TestUnion lobj(1234); PDw{R]V+  
cout<(pszobj)< cout< BSXdvI1y  
return 0; +lp{#1q0  
} ~v: #zU  
ValS8V*N1  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: aIvBY78o  
)teFS %  
class TestUnion 6w#nkF  
{ DBbc|I/[l  
enum StoreType{Long,Const_CharP}; LXhaD[1Rb  
union DataUnion //不能匿名 Qp:6= o0:  
{ d$1 #<-yP  
DataUnion(const char*); //声明const char*构造函数 4nX(:K}>  
DataUnion(long); //声明long构造函数 %"7WXOv&z  
const char* ch_; dl[ob,aCK  
long l_; boQ)fV"  
} data_; rB]W,8~%  
StoreType stype_; *Wyl2op6  
TestUnion(TestUnion&); 0#|7U_n  
TestUnion& operator=(const TestUnion&); t*+! n.p  
public:  t.3 \/  
TestUnion(const char* ch); 0K3Hf^>m  
TestUnion(long l); jmW^`%;7  
operator const char*() const {return data_.ch_;} ~Q!~eTw  
operator long() const {return data_.l_;} B!q?_[k,  
}; ` py}99G  
Ysk, w,K  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) pv$tTWk  
{//注意data_(ch),这里直接引用data_ S|2VP8xY9  
} G:Hj;&'2  
Xu<FDjr  
TestUnion::TestUnion(long l):data_(l),stype_(Long) Pc4R!Tc  
{//注意data_(l),这里直接引用data_ /"0as_L<  
} 2oNV=b[  
u 2lX d'  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) +#v4B?NR  
{ |[wyc!nY).  
} <kc]L x  
0_V*B[V  
TestUnion::DataUnion::DataUnion(long l):l_(l) 7jezw'\=~  
{ lS{4dvr?w  
} lV7IHX1P  
4 ?2g&B\  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八