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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 ZuVes?&j  
sHf.xc  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 yQdoy^d/4  
@DniYt/  
  一、在union中存储对象 M'}iIO`L  
a6epew!2  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? ? yek\X  
|iGfWJ^+  
#pragma warning(disable : 4786) <p\iB'y  
#include HWxwG'EEY,  
using namespace std; {/K_NSg+h  
+/Qgl  
class TestUnion `uLH3sr  
{ +lED6 ]+%  
 public: d'*:2;)g^  
 TestUnion(long l):data_(l) *WK0dn  
 { P,ud"F=r  
  }; 3%DDN\q\u  
 int data_; /d-d8n  
}; JVt(!%K}&  
(^ ;Fyf/  
typedef union _tagUtype_ 5$Da\?Fpn  
{ 0zrZrl  
 TestUnion obj; |}2X|4&X  
}UT; OM 4, Sevk  
?h7(,39^>  
int main (void) >uVr;,=y  
{ BZ"+ ND9m_  
 return 0; jw$[b=sa  
} %\QK/`krp  
C">w3#M%  
3lT>C'qq  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: <P#]U"?A  
cgF?[Z+x  
class TestUnion 5&N55? G6  
{ -3T~+  
 public: |}KNtIX\G  
 int data_; U3 y-cgE  
}; &(t/4)IZox  
8e*1L:oB!  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! P8=!/L2?  
V Mb r@9  
二、类中union的初始化 / +9o?Kxya  
p`}'-A|@  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: & U6bOH%P  
^;gwD4(hs  
#pragma warning(disable : 4786) @ZTsl ?  
#include M->$ 'Zgh`  
R0_O/o+{  
using namespace std; YH^h ?s  
j@4AY}[tX  
class TestUnion v cZg3:j  
{ #I] ^Wo  
enum StoreType{Long,Const_CharP}; ?O.1HEr  
union ;Uv/#"r  
{ #CYDh8X<i  
const char* ch_; w\QMA3  
long l_; NsY D~n  
} data_; OPP^n-iPr  
StoreType stype_; v(vJ[_&%  
TestUnion(TestUnion&); ~qj09  
TestUnion& operator=(const TestUnion&); kjVJ!R\  
public: ne (zGJd  
TestUnion(const char* ch); ?N/6m  
TestUnion(long l); o2 vBY]Tj  
operator const char*() const {return data_.ch_;} +M/1,&  
operator long() const {return data_.l_;} !.}ZlA  
}; T_=iJ: Q  
M)v4>Rw+  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) Obb"#W@3  
{ vl67Xtk4  
} t/`~(0F  
CW9vC  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) a/v!W@Zz}  
{ nnol)|C{5Y  
} 4T<4Rb[  
gvLzE&V}  
int main (void) O<EFm}Ae  
{ U'K{>"~1a  
TestUnion pszobj("yuankai"); ?cRGdLP'D  
TestUnion lobj(1234); 0/@ ^He8l  
cout<(pszobj)< cout< B=p6p f  
return 0; /suW{8A(E  
} |*5803h  
8\H*Z2yF+  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下:   iE8  
t6JM%  
class TestUnion {BS}9jZx  
{ d%wy@h  
enum StoreType{Long,Const_CharP}; Z|k>)pv@  
union DataUnion //不能匿名 _b)=ERBbCo  
{ i3[%]_eP.  
DataUnion(const char*); //声明const char*构造函数 T1YCld  
DataUnion(long); //声明long构造函数 <QcQ.b  
const char* ch_; #FNSE*Y  
long l_; )5NjwLs  
} data_; bCbpJZ  
StoreType stype_; :kb2v1{\  
TestUnion(TestUnion&); U-mZO7y!  
TestUnion& operator=(const TestUnion&); %/:0x:ns  
public: DY(pU/q  
TestUnion(const char* ch); ??u*qO:p  
TestUnion(long l); )oU%++cdo  
operator const char*() const {return data_.ch_;} $]`rWSYtv`  
operator long() const {return data_.l_;} cKM#0dq  
}; aB*'DDlx"r  
F).7%YfY  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) mY 1Gm|  
{//注意data_(ch),这里直接引用data_ *&nIxb60b{  
} {IgL H`@  
;rqW?':(i  
TestUnion::TestUnion(long l):data_(l),stype_(Long) 9(AY7]6  
{//注意data_(l),这里直接引用data_ gx ]5)O  
} m*f"Y"B.1I  
LyuA("xB#  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 6a!b20IZh  
{ >f*-9  
} \M U-D,@  
]p-x ds#d  
TestUnion::DataUnion::DataUnion(long l):l_(l) kIwq%c;  
{ vXLGdv::  
} ;Zt N9l  
JUpb*B_z  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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