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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 dihjpI_  
kRJ4-n^@><  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 21X`h3+=  
Dim> 7Wbh  
  一、在union中存储对象 4BL;FO  
N2r/ho}8  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? uN*KHE+h  
;bzX% f?|G  
#pragma warning(disable : 4786) F9"w6;hh  
#include Ex amD">T  
using namespace std; Uu s.  
;*TIM%6#  
class TestUnion S[3iA~)Z-  
{ {$D,?V@%_  
 public: > et-{(G  
 TestUnion(long l):data_(l) *iO u'  
 { tC?=E#3 V  
  }; n: ui  
 int data_; 5 |0,X<&  
}; MM_k ]-7  
#p(h]T32  
typedef union _tagUtype_ _9 .(a  
{ r|Z3$J{^"  
 TestUnion obj; $``1PJoi  
}UT; !LMN[3M_  
+j_ ;(Gw7  
int main (void) |y;}zQB-dH  
{ 3981ie  
 return 0; VZr>U*J[:  
} {Bs~lC$  
Qf M zF  
OVzt\V*+%W  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: e~%  ;K4  
Pt:e!qX)  
class TestUnion RcG0 8p.)  
{ -H^oXeN  
 public: E907fX[R~  
 int data_; Ix@&$!'k  
}; >zsid:  
/-_=nf}w  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! x5`br.b  
H`bSYjgM!  
二、类中union的初始化 K%<j=c  
:NHH Dl  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: xJ^>pg8  
G@FI0\t  
#pragma warning(disable : 4786) oBQ#eW aY  
#include $E<Esf$  
fqX"Lus `=  
using namespace std; ZRxZume<f  
00I}o%akO  
class TestUnion ? &G`{Ey  
{ E1dD7r\  
enum StoreType{Long,Const_CharP}; ^'CPM6J  
union n~"$^Vr  
{ <?-YTY|  
const char* ch_; `g8E1-]l  
long l_; f0<hE2  
} data_; fH`P[^N  
StoreType stype_; =ph&sn$;L  
TestUnion(TestUnion&); ,g-EW jN  
TestUnion& operator=(const TestUnion&); rk+#GO{  
public: ~7~~S*EQ  
TestUnion(const char* ch); ](tx<3h  
TestUnion(long l); {2/LRPT  
operator const char*() const {return data_.ch_;} <DKS+R  
operator long() const {return data_.l_;} 5$DHn ]  
}; q"O.Cbk  
|b-9b&  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) `p;eIt  
{ M;cO0UIwO  
} D']ZlB 'K  
bwVPtu`  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) j?y LDLj  
{ 5>3}_  
} '1,,)U#6E  
5w%_$x  
int main (void) t*@2OW`!  
{ rg0m a  
TestUnion pszobj("yuankai"); Q9I j\HbA"  
TestUnion lobj(1234); sK{l 9  
cout<(pszobj)< cout< 8^Hn"v  
return 0; V fv@7@q  
} 56^ +;^f^`  
M02uO`Y9  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 4S~o-`&W  
h\plQ[T  
class TestUnion 8N:owK  
{ &_JD)mM5  
enum StoreType{Long,Const_CharP}; 4}_O`Uxh  
union DataUnion //不能匿名 Gl1jxxd  
{ ,Jcm+ Wb  
DataUnion(const char*); //声明const char*构造函数 `cPywn@uGZ  
DataUnion(long); //声明long构造函数 REZJ}%}/  
const char* ch_; S3L~~X/=  
long l_; uwRr LF  
} data_; fLV"T_rk  
StoreType stype_; %6AW7q t  
TestUnion(TestUnion&); 4}`  
TestUnion& operator=(const TestUnion&); pF ^#}L  
public: (D@A74q\'  
TestUnion(const char* ch); /R>nr"  
TestUnion(long l); MCU_Z[N#10  
operator const char*() const {return data_.ch_;} |F9z,cc"  
operator long() const {return data_.l_;} v9Xp97J2  
}; \Mg`(,kwe  
e]jH+IR:>  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Bo<>e~6P  
{//注意data_(ch),这里直接引用data_ R!l:O=[<  
} u:aW 8  
TCT57P#b  
TestUnion::TestUnion(long l):data_(l),stype_(Long) SQeRSz8bK4  
{//注意data_(l),这里直接引用data_ YF+n b.0.  
} dw.F5?j`b  
n@ w^ V   
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) sA gKg=)  
{ P&Pj>!T5  
} mv5n4mav  
?"z]A7<Hj  
TestUnion::DataUnion::DataUnion(long l):l_(l) mxb06u _  
{ n}s~+USZX  
} h"H2z1$  
k}KC/d9.z  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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