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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 o5)lTVQ~~  
PRcW}"m]Qg  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 h BD .IB  
-}Vnr\f  
  一、在union中存储对象 {3cT\u  
|Y?1rLC  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? Ey7SQb  
qC]6g  
#pragma warning(disable : 4786) ;DbEP.%u$  
#include },zP,y:cH  
using namespace std; #m [R1G#  
]  }XsP  
class TestUnion 8i"v7}  
{ <WhdQKFf-  
 public: CR3<9=Lv>  
 TestUnion(long l):data_(l) ErmlM#u  
 { %" kF i  
  }; ~~,] b  
 int data_; o6L\39v_  
}; D>neY9  
W u?A} fH  
typedef union _tagUtype_ m X2i^.zH  
{ lr[U6CJY  
 TestUnion obj; `F-<P%k  
}UT; p,#t[K  
mAO$gHQ  
int main (void) &5k$ v^W5  
{ >G `Uc&=  
 return 0; CWF(OMA  
} rD ^ b{]E3  
Z',Z7QW7  
oihn`DY {  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: kF{'?R5 w  
G':wJ7[]`  
class TestUnion ,6N|?<26O  
{ j~DTvWg<Jl  
 public: o_=t9\:  
 int data_; i3 ?cL4  
}; Fl8*dXG&  
(.r9bl  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! %0-fn'  
ha Tmfh_|  
二、类中union的初始化 ">zK1t5=  
s0EF{2<F  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下:  8kn> ?  
YF)uAJAk  
#pragma warning(disable : 4786) 47<fg&T  
#include )I&,kH)+  
R*S9[fqC[  
using namespace std; 4\?z^^  
(%N=7?  
class TestUnion }.ZT?p\  
{ C_5o&O8Bc  
enum StoreType{Long,Const_CharP}; N+0[p@0  
union ([g[\c,H  
{ '.{tE*  
const char* ch_; d1[;~)  
long l_; JCe%;U  
} data_; O%H c%EfG  
StoreType stype_; `eo$o!  
TestUnion(TestUnion&); :}B=Bk/q  
TestUnion& operator=(const TestUnion&); .<fn+]  
public: S1vUP5cZ  
TestUnion(const char* ch); '}$]V>/  
TestUnion(long l); Yo-$Z-ud  
operator const char*() const {return data_.ch_;} 4LY$;J;2  
operator long() const {return data_.l_;} ZBY*C;[)*P  
}; P* Z1Rs_  
"z8iuF  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) FN+x<VXo(  
{ hD*83_S  
} ByU&fx2Z  
@A.7`*i_  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ;#/Uo8  
{  k00&+C  
} #{8t ?v l  
O)FkpZc@9c  
int main (void) U,g)N[|  
{ IE*5p6IM~  
TestUnion pszobj("yuankai"); 0F5QAR O  
TestUnion lobj(1234); J/k4CV*li(  
cout<(pszobj)< cout< &Hj1jM'  
return 0; HKXtS>7d  
} eWk W,a  
%E\pd@  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 7`P1=`..  
BD_"w]bqD  
class TestUnion yhsbso,5 a  
{ Hw\hTTK  
enum StoreType{Long,Const_CharP}; .-mlV ^  
union DataUnion //不能匿名 M>rertUR  
{ .L=C7w1  
DataUnion(const char*); //声明const char*构造函数 6j6P&[  
DataUnion(long); //声明long构造函数 Rq[VP#  
const char* ch_; ;\],R.!  
long l_; KB`">zq$u  
} data_; cs-dvpMZ  
StoreType stype_; 3bK=Q3N  
TestUnion(TestUnion&); '{F Od_uk%  
TestUnion& operator=(const TestUnion&); &eIwlynm  
public: X B[C&3I  
TestUnion(const char* ch); # n\|Q\W  
TestUnion(long l); q6T>y%|FZ  
operator const char*() const {return data_.ch_;} ,9"A"p*R  
operator long() const {return data_.l_;} 52v@zDY  
};  KrqO7  
s g6e% 5  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Dy|DQ>?}  
{//注意data_(ch),这里直接引用data_ Uv|^k8(  
} Y{c+/n3d  
MngfXm  
TestUnion::TestUnion(long l):data_(l),stype_(Long) )#0Llx!  
{//注意data_(l),这里直接引用data_ ]D\p<4uepM  
} <xaB$}R  
'U{6LSaCb  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) yiAusl;  
{ QV*W#K\7q  
} k}908%w  
Y^ ti;:  
TestUnion::DataUnion::DataUnion(long l):l_(l) 9 :FzSD  
{ vy{YGT  
} nTH!_S>b(Y  
n||!/u)*  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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