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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 x#jJ 0T  
yo]8QO]97  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 Zd~Q@+sH  
1pJ?YV  
  一、在union中存储对象 !~!\=etm  
/ 0y5/  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? fK; I0J  
&]jCoBj+_  
#pragma warning(disable : 4786) 5z@QAQ  
#include IiZXIG4H  
using namespace std; M2piJ'T4u  
9HG"}CGZP  
class TestUnion +1>\o|RF  
{ RWdx) qj{  
 public: P%y$e0  
 TestUnion(long l):data_(l) Po7oo9d  
 { 3 adF) mh  
  }; XT{o ]S~nq  
 int data_; wd<jh,Y  
}; =g<Yi2  
fk'DJf[M  
typedef union _tagUtype_ IvJ5J&!  
{ ku^0bq}BrH  
 TestUnion obj; sV-UY!   
}UT; m?]= =9  
A}MF>.!}C  
int main (void) OJ,Z  
{ <59G  
 return 0; ~NB lJULS  
} !DZ4C.  
0*50uK=5  
gbu@&   
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: Py~N.@(:1u  
=e|  
class TestUnion x_OZdI  
{ "fWm{;  
 public: 4]m?8j) 6b  
 int data_; Ep8 y  
}; yYPFk  
;-d2~1$  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! uV\~2#o$_  
2/RW(U  
二、类中union的初始化 *FC26_pH  
e*hCf5=-  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: O^<\]_l  
~RIa),GVX  
#pragma warning(disable : 4786) RxXiSc`^z  
#include w_9[y  
u!9bhL`  
using namespace std; [J+]1hCZ|  
z[*Y%o8-r  
class TestUnion E9#.!re|^  
{ QI{<q<  
enum StoreType{Long,Const_CharP}; U?(+ {4l  
union 4KZ)`KPE  
{ ~[`*)(4E  
const char* ch_; ErY-`8U"  
long l_; !?J?R-C  
} data_; CV7%ud]E  
StoreType stype_; n_1,-(t  
TestUnion(TestUnion&); t0+D~F(g  
TestUnion& operator=(const TestUnion&); V(<(k,8=  
public: q\T}jF\t  
TestUnion(const char* ch); ~=9]M.$  
TestUnion(long l); D[bPm:\0M  
operator const char*() const {return data_.ch_;} ;ksxz  
operator long() const {return data_.l_;} X2to](\% X  
}; 9<6Hs3|.!  
\aB"D=P\ok  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) g].v  
{ SCKpW#2dP{  
} } f+hB  
HQtUNtZ  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) vp..>BMJ  
{ Uiu9o]n  
} hSfLNvK  
ff<ad l-  
int main (void) ^9xsbv B0  
{ _~_6qTv-d  
TestUnion pszobj("yuankai"); W!4xE  
TestUnion lobj(1234); dxF/]>t  
cout<(pszobj)< cout< 'w!8`LPu  
return 0; fqS cf}s  
} ~#V1Gunq  
7T@"2WYat  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 3:G94cp5  
,Z p9,nf  
class TestUnion :R9 DJh\  
{ /7-qb^V  
enum StoreType{Long,Const_CharP}; AlQ  
union DataUnion //不能匿名 :h)A/k_  
{ @AAkEWo)_  
DataUnion(const char*); //声明const char*构造函数 1PdxoRa4=  
DataUnion(long); //声明long构造函数 o;M-M(EZQ6  
const char* ch_; f+D a W  
long l_; 8et.A  
} data_; }t9A#GOz  
StoreType stype_; P g1EE"N@  
TestUnion(TestUnion&); AC9#!# OGB  
TestUnion& operator=(const TestUnion&); mB]Y;R<  
public: \J?5K l[*c  
TestUnion(const char* ch); 4E.K6=k|=a  
TestUnion(long l); Dt8wd,B  
operator const char*() const {return data_.ch_;} C*fSPdg?  
operator long() const {return data_.l_;} I\peO/w  
}; |? l6S  
SK_i 3?  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) +i.b&PF'H  
{//注意data_(ch),这里直接引用data_ bLpGrGJs  
} ?{M!syD<  
HOY9{>E}z  
TestUnion::TestUnion(long l):data_(l),stype_(Long) /"%QIy'{  
{//注意data_(l),这里直接引用data_ Il9pL~u  
} O`W&`B(*k  
j2"Y{6c  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 1F_ 1bAh$  
{ zPT!Fa`  
} %xWscA%^u  
;Z(~;D  
TestUnion::DataUnion::DataUnion(long l):l_(l) hSyA;*)U  
{ 95CCje{o _  
} smt6).o  
jboQ)NxT!,  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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