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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 &R72$H9C8i  
YO7U}6wBt  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 '8X>,un  
wX"hUu  
  一、在union中存储对象 i?6&4  
=:WZV8@%  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 8v"rM >[  
ebk>e*  
#pragma warning(disable : 4786) *DF3juf~  
#include Y.viOHL  
using namespace std; qk(Eyp  
\3 SY2g8+  
class TestUnion ?gE=hh  
{ dDaV2:4E  
 public: ~`OX}h/Z  
 TestUnion(long l):data_(l)  ?.?)5 &4  
 { e%\^V\L  
  }; Pp8S\%z~h  
 int data_; U6]#RxH  
}; ;t&q|}x"  
l76=6Vtb  
typedef union _tagUtype_ Xsq@E#@S  
{ *'/,  
 TestUnion obj; 0WUBj:@g  
}UT; k)p` x"To  
B@,r8)D  
int main (void) .q@?sdGD  
{ Ww]$zd-bo  
 return 0; ;'"'|} xn  
} vhrf89-q  
<>] DcA  
uk):z$ x  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: H bKE;N  
d6luksO*9  
class TestUnion <|Td0|x _q  
{ cI=6zMB  
 public:  >;fVuy  
 int data_; ;.>*O oe&  
}; Cy~IB [  
|p|Zv H  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Ds`e-X)O;\  
2@|`Ugjptl  
二、类中union的初始化 ]EiM~n  
iiPVqU%  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: X{-4w([  
11H`WOTQF  
#pragma warning(disable : 4786) L< F8+a7i  
#include E'AR.!  
CsO!Y\'FY  
using namespace std; P3zUaN \c  
RM2Ik_IH[l  
class TestUnion ewMVUq*:  
{ w 3t,S3!  
enum StoreType{Long,Const_CharP}; mrTf[ "K  
union Ni_H1G  
{ _Id'56N]J!  
const char* ch_; dN{At-  
long l_; y~9wxK  
} data_; ~MG6evm &  
StoreType stype_; 4 2Z:J 0  
TestUnion(TestUnion&); |9E:S  
TestUnion& operator=(const TestUnion&); 5GsmBf$RUb  
public: TDh)}Ms  
TestUnion(const char* ch); +IdM|4$\1  
TestUnion(long l); PUdv1__C  
operator const char*() const {return data_.ch_;} xWLvx'8W  
operator long() const {return data_.l_;} CNB weM  
}; I,?NYIG"(  
)&c2+Y@  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) c2E /-n4K@  
{ A2'i~_e  
} 4) 8k?iC*  
i fsh(^N  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) LRJX>+@  
{ +:KZEFY?<  
} i).%GMv*r  
V+gZjuN$  
int main (void) AiqKf=  
{ LO`0^r  
TestUnion pszobj("yuankai"); 46?z*~*G  
TestUnion lobj(1234); W{,fpm  
cout<(pszobj)< cout< )UR$VL  
return 0; A*h8 o9M  
} W|PAI [N  
r_7%|T8  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: vXJs.)D7  
!wYN",R-  
class TestUnion ?JuJu1  
{ pH'Tx>  
enum StoreType{Long,Const_CharP}; ^twyy9VR  
union DataUnion //不能匿名 iq;\},  
{ 579Q&|L.  
DataUnion(const char*); //声明const char*构造函数 e,(Vy  
DataUnion(long); //声明long构造函数 N.|F8b]v  
const char* ch_; T8 FW(Gw#  
long l_; mR0`wrt  
} data_; (j8*F Bq  
StoreType stype_; @-q,%)?0}=  
TestUnion(TestUnion&); z teu{0  
TestUnion& operator=(const TestUnion&); ,N$Q']Td  
public: (:iMs) iO{  
TestUnion(const char* ch);  ][ $UN  
TestUnion(long l); RXXHg  
operator const char*() const {return data_.ch_;} dDcQSshL  
operator long() const {return data_.l_;} 5hE#y]pfN  
}; ~kc#"^s J  
Y.m1d?H 1  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) 5gz^3R|`f  
{//注意data_(ch),这里直接引用data_ Q& [!+s:2J  
} uP9b^LEoN  
2CC"Z  
TestUnion::TestUnion(long l):data_(l),stype_(Long) c)EYX o  
{//注意data_(l),这里直接引用data_ z%}"=  
} |!oC7!+0^  
PMQTcQ^  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) a~KtH;7<  
{ IADSWzQ@  
} -jjB2xP  
8:Hh;nl  
TestUnion::DataUnion::DataUnion(long l):l_(l) ^#5'` #t  
{ HNkOPz+d&8  
} d V%o:@Z  
 (?Ku-k  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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