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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 ?TEdGe\*  
+VdC g_  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 ^7$V>|  
sH `(y)`_  
  一、在union中存储对象 jI~GRk  
XTPf~Te,=  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 2nA/{W\hC  
{Bm7'%i  
#pragma warning(disable : 4786) &&er7_Q  
#include j%@wQVxq  
using namespace std; F` "bMS  
2j( ]Bt:  
class TestUnion 'D<84|w:1  
{ X4dXO5\  
 public: NAt; r  
 TestUnion(long l):data_(l) AW< z7B D  
 { /%9CR'%*c  
  }; :rhh=nHgn  
 int data_; g_2EH  
}; 2pn8PQfg)  
vivU4:uH3  
typedef union _tagUtype_ ;"j>k>tg  
{ 7PG|e#  
 TestUnion obj; G$_=rHt_%  
}UT; 6p1)wf.J  
.L'eVLQe  
int main (void) :3$-Qv X  
{ +ZU@MOni  
 return 0; \qB:z7I2  
} IolKe:'>@  
:HTV8;yc  
f{j (H?5  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: /O/pAu>  
"{Jq6):mp  
class TestUnion u~VvGLFf5,  
{ c"x-_Uk  
 public: ];VJ54  
 int data_; "O j2B|:s&  
}; 3El5g0'G  
B9(e"cMm  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! C0. bjFT|  
bX*c-r:  
二、类中union的初始化 ji :E  
wS%aN@ay3  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: H% "R _[+  
>y7|@'V[v0  
#pragma warning(disable : 4786) DS]C`aM9  
#include "FfIq;  
=p29 }^@@t  
using namespace std; Q@HW`@i  
8M9}os  
class TestUnion wdzZ41y1  
{ Y]-7T-*+t  
enum StoreType{Long,Const_CharP}; -D-]tL6w  
union UxS@]YC  
{ \yNe5  
const char* ch_; 4(O;lVT}  
long l_; Z;4pI@ u  
} data_; ->29Tns  
StoreType stype_; sn6:\X<[  
TestUnion(TestUnion&); C^W9=OH  
TestUnion& operator=(const TestUnion&); lX*IEAc  
public: &hri4p/  
TestUnion(const char* ch); uBXl ltU  
TestUnion(long l); *4oj' }  
operator const char*() const {return data_.ch_;} tH\ aHU[  
operator long() const {return data_.l_;} ;4] sP^+  
}; Fo86WP}  
nL]-]n;  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) @& vtY._  
{ 2^.qKY@g@  
} B^C!UWN>%X  
{:m%n-  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) d9>k5!  
{ rs?"pGz;  
} JVx ,1lth  
uv$t>_^  
int main (void) ? pkg1F7  
{ B]-~hP  
TestUnion pszobj("yuankai"); )of?!>'S[  
TestUnion lobj(1234); tbr1mw'G  
cout<(pszobj)< cout< G*x"drP  
return 0; 6;8Jy  
} z/&2Se:  
"`'' eV3  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: qh<h|C]V  
_xVtB1@kLM  
class TestUnion RCvf@[y4  
{ / Q8glLnM  
enum StoreType{Long,Const_CharP}; KNZN2N)wR  
union DataUnion //不能匿名 ` e~nn  
{ ]l.qp5eQ  
DataUnion(const char*); //声明const char*构造函数 t:?8I9d  
DataUnion(long); //声明long构造函数 gfW8s+  
const char* ch_; .tny"a&  
long l_; 4?s ~S. %  
} data_; &!E+l<.RF  
StoreType stype_; E)h&<{%  
TestUnion(TestUnion&); }VUrn2@-4  
TestUnion& operator=(const TestUnion&); ~c*$w O\  
public: 8ezdU"  
TestUnion(const char* ch); Rl2*oOVz  
TestUnion(long l); W@( EEMhw  
operator const char*() const {return data_.ch_;} O%KP,q&}Y  
operator long() const {return data_.l_;} & &\HE7*  
}; y>DvD)  
'Lb- +X,  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) ?z]h Ysy  
{//注意data_(ch),这里直接引用data_ -(Y(K!n  
} %Gk?f=e  
(g8<"< N?  
TestUnion::TestUnion(long l):data_(l),stype_(Long) =ZaTD-%id  
{//注意data_(l),这里直接引用data_ ee0)%hc1t  
} vg6 ' ^5S7  
jZX2)#a!  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) @TTB$  
{ }%;o#!<N(@  
} V&75n.L  
j~)GZV  
TestUnion::DataUnion::DataUnion(long l):l_(l) uR:@7n  
{ @},25"x)  
} p[zKc2TPk  
vA r fsgk  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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