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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 W[qQDn!r  
-'uz%2 {  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 qa,i:T(w  
#@:GLmD%  
  一、在union中存储对象 (%)<jg1  
<P_B|Y4N/  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? uF\ ;m.  
XXy &1C  
#pragma warning(disable : 4786) m^KK #Hw/`  
#include 2`pg0ciX (  
using namespace std; MX s]3M  
I` q"  
class TestUnion 6]fz;\DgP  
{ .&rL>A2U  
 public: ;oWak`]f  
 TestUnion(long l):data_(l) w">-r}HnJ  
 { K9c5HuGy  
  }; bj_oA i  
 int data_; .-}F~FES  
}; lj 2OOU{  
 K2D, *w  
typedef union _tagUtype_ =6xxZy[  
{ wY*tq{7  
 TestUnion obj; aK]H(F2#  
}UT; "p"~fN /I9  
 lx&;?QQ  
int main (void) \s_`ZEB  
{ G$E+qk nJL  
 return 0; NU%<Ws=  
} li&&[=6A  
)BmO[AiOM  
p* tAwl  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: 6MmkEU z  
5^Ps(8VbS  
class TestUnion L~HL*~#d  
{ Qn`Fq,uvL  
 public: v|wO qS  
 int data_; .NT9dX  
}; M"E7= J  
oNp(GQ@0  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! {xCqz0  
CYZ0F5+t  
二、类中union的初始化 n0opb [?  
0l2@3}e  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: fu{.Ir  
~c${?uf   
#pragma warning(disable : 4786) {J]x81}*;  
#include 7(B"3qF8|  
N.?)s.D(  
using namespace std; hi^t zpy  
jn+BH3e  
class TestUnion Bb*P);#.K  
{ -}9>#<v  
enum StoreType{Long,Const_CharP}; ~ }?*v}  
union X^)v ZL?  
{ qORRpWyx&  
const char* ch_; Mc<O ~  
long l_; ObSRd$M  
} data_; aLO'.5 ~^  
StoreType stype_; Gk]6WLi  
TestUnion(TestUnion&); ?(>fB2^  
TestUnion& operator=(const TestUnion&); eY8rm  
public: >rid3~  
TestUnion(const char* ch); ?VR:e7|tU  
TestUnion(long l); 4x2,X`pe3  
operator const char*() const {return data_.ch_;} P:fcbfH+  
operator long() const {return data_.l_;} E @7);i5K  
}; x#}{z1op9  
g @qrVQv  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) h4tAaPcS+  
{ LuvRxmQ`  
} ' ;3#t(J;  
!b8.XGo  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) Q[MWzsx  
{ :bu]gj4e  
} ><H*T{ Pg  
UflS`  
int main (void) .?)gn]#  
{ 6 B*,Mu4A  
TestUnion pszobj("yuankai"); v&Oc,W  
TestUnion lobj(1234); 2dnyIgi  
cout<(pszobj)< cout< 'yNS(Bg=  
return 0; Zx 5Ue#I  
} t>JPK_b0  
-;j ' =?  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: Z Z9D6+R  
9;R'Xo=y  
class TestUnion tWaM+W  
{ H,0Io  
enum StoreType{Long,Const_CharP}; a}[ 1*_G  
union DataUnion //不能匿名 @3Gr2/a  
{ /<Yz;\:Jy  
DataUnion(const char*); //声明const char*构造函数 NM4b]>   
DataUnion(long); //声明long构造函数 +AYB0`X)  
const char* ch_; bz|-x"qk  
long l_; dT'd C  
} data_; ?XB[awTD~  
StoreType stype_; R_2T"  
TestUnion(TestUnion&); J4#rOS  
TestUnion& operator=(const TestUnion&); nWFU8u%  
public: IM=3n%6  
TestUnion(const char* ch); Q|(G -  
TestUnion(long l); XB;C~:  
operator const char*() const {return data_.ch_;} !U4<4<+  
operator long() const {return data_.l_;} % 9} ?*U  
}; AI#.G7'O  
"I0F"nQ  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) XU|>SOR@z  
{//注意data_(ch),这里直接引用data_ ~TYpq;rq  
} PgdHH:v)  
0F9p'_C  
TestUnion::TestUnion(long l):data_(l),stype_(Long) D8f4X w}=  
{//注意data_(l),这里直接引用data_ 1Uk Gjw1J  
} D|D) 782  
>b2wFo/em  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) S(PU"}vZy  
{ 'w?}~D.y  
} 5F$~ZDu  
HUalD3 \  
TestUnion::DataUnion::DataUnion(long l):l_(l) 'g:.&4x_w  
{ 0bl8J5Ar5  
} D.*o^{w|  
k nljc^  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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