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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 VZlvmN  
yxQAO_C  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 v <Ze$^ e&  
)J88gMk+  
  一、在union中存储对象 RBgkC+2  
a m zw  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ;09J;sf  
Q}.y"|^  
#pragma warning(disable : 4786) |)JoxqR  
#include _&![s]  
using namespace std; ^9b `;}).  
L,4 ^Of  
class TestUnion n _ez6{  
{ :3n.nKANr  
 public: D3lYy>~d5;  
 TestUnion(long l):data_(l) kWz%v  
 { rqh,BkQ0t  
  }; 1k%ko?  
 int data_; Yh%wf3 UEO  
}; *wF:Q;_<z  
g4$%)0x%  
typedef union _tagUtype_ Zz&i0 r  
{ 0 De M  
 TestUnion obj; mVL,J=2  
}UT; E;d 5$  
CC-:dNb  
int main (void) z|?R=;,u`  
{ coFg69\^  
 return 0; O`0$pn  
} I~qiF%?d  
4K;j:ZJ"x  
n)7icSc  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: G-(c+6Mn  
)?bb]hZg?O  
class TestUnion :d2u?+F  
{ t(rU6miN  
 public: G-^ccdT  
 int data_; pz IMj_  
}; yl 8v&e{  
J3.Q8f  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! .M{[J]H`t  
Q%xY/xH]  
二、类中union的初始化 ?(<AT]hV:  
9c7 }-Go  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: udZ: OU<  
-9*WQU9R  
#pragma warning(disable : 4786) eztk$o  
#include B;~agr  
!Cy2>6v7  
using namespace std; *pD;AU  
VfcQibm  
class TestUnion lmcDA,7  
{  ck~xj0  
enum StoreType{Long,Const_CharP}; c-=0l)&'D=  
union bX(*f>G'  
{ wqOhJYc  
const char* ch_; C|zH {.H  
long l_; wf@2&vJ  
} data_; %Nn'p"  
StoreType stype_; !m|%4/ M@  
TestUnion(TestUnion&); 7 f*_  
TestUnion& operator=(const TestUnion&); e`Yns$x  
public: RM+E  
TestUnion(const char* ch); KRZV9AJ  
TestUnion(long l); U.F65KaKF  
operator const char*() const {return data_.ch_;} /nP=E  
operator long() const {return data_.l_;} 6;pREM+  
}; MX0B$yc$  
WLl9>v^1  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) j1kc&(  
{ !~l%6Z5  
} zNf5OItx  
cj#q7  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) %$x FnGb  
{ y)E2=JQA/  
} ):@%xoF5  
%nh'F6bNgv  
int main (void) R4(8]oUW  
{ -*M:OF"Zh  
TestUnion pszobj("yuankai"); P[K=']c  
TestUnion lobj(1234); fNJ;{&#  
cout<(pszobj)< cout< %4Zy1{yKs_  
return 0; fdG.=7`  
} 6I#DlAU@v  
$\!;*SSj  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: ?63JQ.;  
uP]o39b;V  
class TestUnion ] O>7x  
{ A%2}?Ds  
enum StoreType{Long,Const_CharP}; Z5[:Zf?h7J  
union DataUnion //不能匿名 sK?-@  
{ 8Q -F  
DataUnion(const char*); //声明const char*构造函数 U9 *2< c  
DataUnion(long); //声明long构造函数 Oha g%<1#  
const char* ch_; N=wy)+  
long l_; y}HC\A77uD  
} data_; n5/Tn7hY  
StoreType stype_; 3raA^d3!?  
TestUnion(TestUnion&); ^b %8_?2m  
TestUnion& operator=(const TestUnion&); J"%}t\Q  
public: T_[\(K`w!  
TestUnion(const char* ch);  ]:fCyIE  
TestUnion(long l); & }}WP:U  
operator const char*() const {return data_.ch_;} :Qo  
operator long() const {return data_.l_;} 5z ^UQ q  
}; 9%14k  
QJM!Wx+  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) mm-UQ\h  
{//注意data_(ch),这里直接引用data_ "\r~,S{:  
} <SZO- -+lB  
XSjelA?  
TestUnion::TestUnion(long l):data_(l),stype_(Long) Z<<gz[$+p  
{//注意data_(l),这里直接引用data_ f {Z%:H  
}  ja- ~`  
i(iP}: 3  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) ?(8%SPRk  
{ y?#J`o- O  
} ; S ` -9}6  
(x0*(*A}  
TestUnion::DataUnion::DataUnion(long l):l_(l) /t)c fFM  
{ ~"2@A F  
}  ca*[n~np  
yGG B  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
欢迎提供真实交流,考虑发帖者的感受
认证码:
验证问题:
10+5=?,请输入中文答案:十五