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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 Mi]L]-L  
#> j.$2G>  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 7"8hC  
+[5.WC7J  
  一、在union中存储对象 Qx[t /~  
qIld;v8w"g  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? <!pY$  
!qX_I db\  
#pragma warning(disable : 4786) ,\qs4&  
#include {dmj/6Lc  
using namespace std; ar:+;.n  
byv[yGa`  
class TestUnion !"eIV@7  
{ Y5F]:gs@  
 public: otk}y8  
 TestUnion(long l):data_(l) U#3J0+!  
 { hUYd0qEbEt  
  }; H<^/Ati,|  
 int data_; <n(*Xak{a  
}; =2@B&  
A'2w>8  
typedef union _tagUtype_ Offu9`DiZ  
{ B, 9w0  
 TestUnion obj; \?jeWyo  
}UT; NMA}Q$o s  
jAud {m*T  
int main (void) 9;veuX#(  
{ $^@)  
 return 0; wQRZ"ri,  
} ^$ t7+g  
s+Q~~]HJM  
>Jp:O 7  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: q `pP$i:  
|^A;&//  
class TestUnion YX` 7Hm,  
{ :sC qjz  
 public: ;&ASkI  
 int data_; 9~l hsH  
}; yrR1[aT  
HeG)/W?r  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! .-<k>9S7_  
,mj@sC>  
二、类中union的初始化 p ZZc:\fJ  
_r2J7&  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: ai{Sa U  
x:QgjK  
#pragma warning(disable : 4786) ;$z$@@WC  
#include P LueVz  
e#E2>Bj;  
using namespace std; lEV]4 t_H  
9 -rNw?7  
class TestUnion 0=K9`=5d0  
{ 4n4?4BEn  
enum StoreType{Long,Const_CharP}; hiUD]5Kp  
union 0@EwM  
{ D_x +:1(  
const char* ch_; 4T=u`3pD7l  
long l_; kV3 8`s>+  
} data_; ~j<+k4I~  
StoreType stype_; 3"P }n  
TestUnion(TestUnion&); 5sb\r,kW  
TestUnion& operator=(const TestUnion&); ` P9XqWr  
public: 5Lf{8UxI  
TestUnion(const char* ch); qkC/\![@  
TestUnion(long l); ak;*W  
operator const char*() const {return data_.ch_;} A]DTUdL  
operator long() const {return data_.l_;} 4)("v-p  
}; !=N"vD*  
*guoWPA|Ij  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) d20gf:@BM  
{ ZfB " E  
} Yboiw y,n  
PP!SK2u "L  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) A$w4PVS  
{ x l#LrvxI  
} }oNhl^JC  
n+PzA[  
int main (void) 'z[Sp~I\  
{ SGe^ogO"v  
TestUnion pszobj("yuankai"); g]c6& Y,#  
TestUnion lobj(1234); rSJ9 v :  
cout<(pszobj)< cout< ?|39u{  
return 0; M{*Lp6h  
} Uy$)%dYfq5  
p1|f<SF')  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: o9H^?Rut  
qcN'e.A  
class TestUnion X#e1KZ  
{ MzL1Bh!M  
enum StoreType{Long,Const_CharP}; ]Ei0d8Uo  
union DataUnion //不能匿名 @U2qD  J6  
{ sxt-Vs7+6  
DataUnion(const char*); //声明const char*构造函数 IhA*"  
DataUnion(long); //声明long构造函数 (e[}/hf6  
const char* ch_; Q_Gi]M9  
long l_; t8dm)s[r8  
} data_; PoT`}-9  
StoreType stype_; M-giR:,  
TestUnion(TestUnion&); `3hSL R  
TestUnion& operator=(const TestUnion&); pi ,eIm  
public: X3V'Cy/sy  
TestUnion(const char* ch); V7Mh-]  
TestUnion(long l); iySRY^  
operator const char*() const {return data_.ch_;} 1Y]TA3:  
operator long() const {return data_.l_;} /=gOa\k|p  
}; 2^l[(N  
G^` 1]?  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) \xS&v7b  
{//注意data_(ch),这里直接引用data_ B}&xaY  
} EMfdBY5  
n;:rf7hGY  
TestUnion::TestUnion(long l):data_(l),stype_(Long) )kkhJI*v  
{//注意data_(l),这里直接引用data_ wy}k1E'M  
} >`%'4<I  
J;f!!<l\  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 7IjQi=#:  
{ )-`;1ca)s  
} r9ww.PpNk#  
"1HRLci  
TestUnion::DataUnion::DataUnion(long l):l_(l) k+DR]icv  
{  $O dCL  
} E,f>1meN=  
p^'3Odd|O  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录 或 注册
如果您在写长篇帖子又不马上发表,建议存为草稿
认证码:
验证问题:
10+5=?,请输入中文答案:十五