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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 5po' (r|U  
C!k9JAa$Z  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 =C>`}%XT}  
zQ %z "tQ  
  一、在union中存储对象 2*wO5v  
 >fA@tUQB  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? m?% H<4X  
>VUQTg  
#pragma warning(disable : 4786) nk|N.%E  
#include &z X 3  
using namespace std; giPo;z\c  
/uXRZ  
class TestUnion [^}>AC*im  
{ <*Kh=v  
 public: t^_{5  
 TestUnion(long l):data_(l) \i;&@Kp.N  
 { 6`baQ!xc.  
  }; 6Vbv$ AU  
 int data_; >{qK ]xj  
}; I<(.i!-x  
V*7Z,nA  
typedef union _tagUtype_ !eAdm  
{ kbp( a+5  
 TestUnion obj; ={E!8"  
}UT; 6SBvn%  
p@7i=hyt`p  
int main (void) *(&ClUQQ  
{ .4C[D{4  
 return 0; >yA,@%X  
} ^A "lkV7  
K l0tyeT  
+>WC^s  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: 3ES[ N.V#  
jo;uRl  
class TestUnion ZG/8Ds  
{ ]%<Q:+38  
 public: &e]]F#  
 int data_; Ce5w0&VlS  
}; hi3sOK*r;<  
O? Gl4_y  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! <[y$D=n  
$]H=  
二、类中union的初始化 hLytKPgt  
:ONuWNY N  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: lO2T/1iMTW  
[71#@^ye  
#pragma warning(disable : 4786) ]oas  
#include X=p3KzzX  
&J^4Y!gt  
using namespace std; ^/DII`A  
{NY~JFM  
class TestUnion yXTK(<'  
{ -q&7J' N  
enum StoreType{Long,Const_CharP}; "0H56#eW  
union oWx_O-_._  
{ R7B,Q(q2-  
const char* ch_; :e&n.i^  
long l_; gVnws E  
} data_; u JQaHL!  
StoreType stype_; dm,}Nbc91(  
TestUnion(TestUnion&); (,Ja  
TestUnion& operator=(const TestUnion&); q M_/  
public: ne"?90~  
TestUnion(const char* ch); x!C8?K =|  
TestUnion(long l);  M<Wn]}7!  
operator const char*() const {return data_.ch_;} .@i0U  
operator long() const {return data_.l_;} ]~prR?  
}; Y%fVt|  
{C/L5cZ]J  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) wTlK4R#  
{ z#{ 0;t  
} 0;FqX*  
Gin_E&%g  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) q[)q|R|  
{ ]|,q|c,  
} 5 PGlR!^  
dSe8vA!)  
int main (void) b.R!2]T]i^  
{ SLdN.4idK  
TestUnion pszobj("yuankai"); Hbjb7Y?[  
TestUnion lobj(1234); vnC<*k4&v  
cout<(pszobj)< cout< RGl=7^M  
return 0; n^iNo  
} Np|'7D  
>~5lYD  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: \K?(  
c Pq Dsl3  
class TestUnion X-)RU?  
{ fO^e+M z  
enum StoreType{Long,Const_CharP}; cBLR#Yu;O5  
union DataUnion //不能匿名 AXl!cgi  
{ j{{~ZM  
DataUnion(const char*); //声明const char*构造函数 t['k%c  
DataUnion(long); //声明long构造函数 'dIX=/RZ  
const char* ch_; v[{8G^Z}54  
long l_; >d8x<|D  
} data_; sK`~Csb iB  
StoreType stype_; *L%6qxl`V  
TestUnion(TestUnion&); %RQC9!  
TestUnion& operator=(const TestUnion&); j3x^<a\gJ  
public: <%d51~@={I  
TestUnion(const char* ch); O{k89{  
TestUnion(long l); E0"10Qbi  
operator const char*() const {return data_.ch_;} I 1b  
operator long() const {return data_.l_;} $J QWfGwR  
}; ,4^9cFVo  
Iv$:`7|crX  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) q&XCX$N  
{//注意data_(ch),这里直接引用data_ M.ZEqV+k  
} jWH{;V&ZV  
f^W[; w  
TestUnion::TestUnion(long l):data_(l),stype_(Long) E?30J3S  
{//注意data_(l),这里直接引用data_ 1Pk mg%+  
} iNod</+"K  
.FIt.XPzv  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) omM&{ }8g  
{ ~ X-)_zH  
} p?+lAbe6H  
Sa3I?+  
TestUnion::DataUnion::DataUnion(long l):l_(l) B{7Kzwh;  
{ 1.# |QX  
} dB@Wn!Y  
q} ]'Q -  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八