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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 `+cc{k  
Y S )Q#fP  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 B*#lkMr  
zsnXPRF  
  一、在union中存储对象 WVlyR\.  
GF[onfQY7  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? &|'k)6Rx  
qg6283'?  
#pragma warning(disable : 4786) ousvsP%'  
#include n 5h4]u  
using namespace std;  K9 h{sC  
IF-g %  
class TestUnion wd&Tf R4!  
{ ew8f7S[  
 public: V'y,{YpP  
 TestUnion(long l):data_(l) $6Z@0H@X  
 { 9M{z@H/  
  }; 53X H|Ap  
 int data_; X;/~d>@  
}; G\4h4% a  
2;N)>[3*J  
typedef union _tagUtype_ *CG-F=  
{ #wn`choT'  
 TestUnion obj; J+ tpBPmb  
}UT; _GSl}\  
t_cNH@^3<3  
int main (void) 5lehASBz  
{ _s{on/u  
 return 0; #1c%3KaZ I  
} b`M  2VZu  
R >1  
q))r lMo  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: ZdQt!  
*V}T}nK7  
class TestUnion U'8+YAgc  
{ 4 0as7.q  
 public: {T EF#iF  
 int data_; i!5zHn  
}; CsfGjqpf  
@ov*Fh  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! Hxe!68{aR  
dJ~AMol  
二、类中union的初始化 O~Eju  
? I7}4i7  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: .URCuB\{  
-'ff0l  
#pragma warning(disable : 4786) %dA6vHI,  
#include aYc*v5Q N3  
RJ+i~;-  
using namespace std; 'a8{YT4  
Fo  K!JX*  
class TestUnion -L=aZPW`M  
{ >9F&x>~  
enum StoreType{Long,Const_CharP}; UbDRzum  
union ;jC}.] _)w  
{ 4O}ZnE1[  
const char* ch_; 3^NHV g  
long l_; BC|=-^(  
} data_; h+ixl#:  
StoreType stype_; x93t.5E6  
TestUnion(TestUnion&); yb{ud  
TestUnion& operator=(const TestUnion&); 1nHQ)od  
public: BllS3I}V  
TestUnion(const char* ch); =z_.RE  
TestUnion(long l); iKs @oHW  
operator const char*() const {return data_.ch_;} AXbDCDA  
operator long() const {return data_.l_;} @K{1O|V  
}; %#5yC|o9Pn  
tkQ#mipAj  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) SvE3E$*  
{ LHit9O[_/s  
} &d1|B`gL|  
OUoN  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) y;oPg4  
{ fGK=lT$  
} >iE/t$%1  
UEkn@^&bg  
int main (void) K ?R* )_  
{ !h\>[O  
TestUnion pszobj("yuankai"); 6k569c{7  
TestUnion lobj(1234); ([vyY}43h  
cout<(pszobj)< cout< 9 GEMmo3  
return 0; @D$^- S6  
} Tvdg:[V<  
D}.Pk>5  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: )w3?o#@  
=8`!Ph@(  
class TestUnion _[J @w.l(  
{ J/OG\}  
enum StoreType{Long,Const_CharP}; <]{$XcNm  
union DataUnion //不能匿名 Y z"B  
{ [WZGu6$SU  
DataUnion(const char*); //声明const char*构造函数 J3 Y-d7=|  
DataUnion(long); //声明long构造函数 k :KN32%  
const char* ch_;  3W& f^*  
long l_; /=o~7y  
} data_; Pn&!C*,  
StoreType stype_; DjzHEqiH  
TestUnion(TestUnion&); H > Y0R  
TestUnion& operator=(const TestUnion&); FBDRbJ su  
public: F?h{IH f  
TestUnion(const char* ch); hDPZj#(c  
TestUnion(long l); >"Tivc5  
operator const char*() const {return data_.ch_;} -L zx3"  
operator long() const {return data_.l_;} S}mZU!  
}; h!@t8R  
3 VNPdXsh  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) ]'  ck!eG  
{//注意data_(ch),这里直接引用data_ S_ELZO#7  
} ^a,Oi%  
3mmp5 d  
TestUnion::TestUnion(long l):data_(l),stype_(Long) }vx+/J  
{//注意data_(l),这里直接引用data_ fLGZ@-qA0  
} i!AFXVX  
$-x@P9im  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) ?o0ro?9j  
{ .k_> BD];  
} H]zi>;D  
6R`q{}.  
TestUnion::DataUnion::DataUnion(long l):l_(l) B<V8:vOam  
{ KM'*+.I  
} VaV(+X  
|IN{8  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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