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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 iyN:%ofh  
AJt+p&I[J  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 Qd)q([  
>u>5{4  
  一、在union中存储对象 RPwbTAl}  
D{!6Y*d6&s  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? `CBZhI%%  
H[m:0eF'5  
#pragma warning(disable : 4786) ~3^ 8>d/  
#include B`YTl~4  
using namespace std; LuNc, n%  
_uWpJhCT  
class TestUnion ?fiIwF)  
{ 7jxslI&F  
 public: }\hVy(\c  
 TestUnion(long l):data_(l) )5rb&M}  
 { Ut*`:]la  
  }; 8G9s<N}5&u  
 int data_; YA''2Ii  
}; \?w2a$?6w  
%]F d[pzF  
typedef union _tagUtype_ cIUHa  
{ &@G:G(  
 TestUnion obj; P !AEf#1  
}UT; B+Rm>^CBm  
k\wW##=v  
int main (void) b v G/|U  
{ oin$-i|Xp!  
 return 0; ?iPC*  
} >x/z7v?^I  
gRrL[z  
DD7h^-x  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: BYpG  
+GG9^:<yr  
class TestUnion *Tas`WA  
{ 4^:\0U F  
 public: bmJ5MF]_fG  
 int data_; ztnFhJ<a$  
}; ?b*s. ^  
V E#Wb7  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! kEJj=wx  
rEv@Y D  
二、类中union的初始化 VkvB<3  
RzxNbeki[W  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: C+'/>=>a.  
'r4/e-`pK  
#pragma warning(disable : 4786) Mx&&0#;r  
#include {,3>"  
B&\IGWG(  
using namespace std; W6f/T3  
AZ0;3<FfLp  
class TestUnion H+1-]'g`  
{ ,X#2\r<|  
enum StoreType{Long,Const_CharP}; 9G9fDG#F\I  
union N8k00*p65  
{ 2w59^"<,  
const char* ch_; +s(HOq)b  
long l_; @AG n{q  
} data_; 0F]>Jby  
StoreType stype_; ./,/y"x  
TestUnion(TestUnion&); b8~Bazk  
TestUnion& operator=(const TestUnion&); B$- R-S6  
public: V`X2> -Ex  
TestUnion(const char* ch); <%($7VMev  
TestUnion(long l); JM=JH 51`  
operator const char*() const {return data_.ch_;} }#.L7SIJ<J  
operator long() const {return data_.l_;} "*m_> IU  
}; $8;R[SU6Y  
[ad@*KFxy3  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) *-MM<|Qt  
{ '{E@*T /<.  
} txW{7+,  
-j%,Oo  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) TFH\K{DM  
{ :axRoRg  
} a&tSj35*6  
+,2:g}5  
int main (void) 9  TvV=  
{ "^4_@ oo  
TestUnion pszobj("yuankai"); k,'L}SK  
TestUnion lobj(1234); A9f)tqbc  
cout<(pszobj)< cout< .l>77zM6  
return 0; f%Ns[S~r  
} M*z~gOZ  
/]=C{)8  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: (5#nrF]  
>SML"+>  
class TestUnion |K6REkzr  
{ 9F4Dm*_<  
enum StoreType{Long,Const_CharP}; <Fi%iA  
union DataUnion //不能匿名 {XNREjhm  
{ j/>$,   
DataUnion(const char*); //声明const char*构造函数 b?TO=~k,  
DataUnion(long); //声明long构造函数 V^JV4 `o  
const char* ch_; U'8bdsF_  
long l_; lp<g \  
} data_; Qj,]N@7  
StoreType stype_; *RXbc~ H  
TestUnion(TestUnion&); S/^"@?z,vE  
TestUnion& operator=(const TestUnion&); VTG9$rQZ  
public: &0NFb^8+  
TestUnion(const char* ch); k *Q<3@S  
TestUnion(long l); 2W/?q!t  
operator const char*() const {return data_.ch_;} @\0Eu212  
operator long() const {return data_.l_;} CZ(/=3,3n  
}; 6,d@p  
]3VI|f$$  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) y$@ZN~8  
{//注意data_(ch),这里直接引用data_ D[^m{ 9_  
} Gs9:6  
@c<3b2  
TestUnion::TestUnion(long l):data_(l),stype_(Long) R(2tlZ  
{//注意data_(l),这里直接引用data_ hJDi7P  
} c%&: 6QniZ  
{P{bOe  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) zY,r9<I8_x  
{ T(e!_VY|m  
} NbC@z9Q  
@r#v[I  
TestUnion::DataUnion::DataUnion(long l):l_(l) BB~OqZIP  
{ hg+X(0  
} QS{1CC9$  
bKrhIU[  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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