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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 j;y|Ys)I  
gky_]7Av  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 1)R)+`y  
C[pDPx,#:G  
  一、在union中存储对象 +?<jSmGW  
%G@aZWk Sa  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? gMvvDP!Wp  
m\>x_:sE  
#pragma warning(disable : 4786) |<V{$),k  
#include JU@$(  
using namespace std; xpxm9ySwu  
3pp w_?k  
class TestUnion bDo'hDmW  
{ >H1d9y +Z  
 public: (wfg84  
 TestUnion(long l):data_(l) %FU[ j^  
 { B<R-|-#  
  }; T82_`u  
 int data_; cTnbI4S;  
}; -0`hJ_(  
;x#>J +QlG  
typedef union _tagUtype_ {<2Zb N?  
{ 54{"ni 2a  
 TestUnion obj; ,2`d3u^CW  
}UT; H1[aNwLr  
%awS*  
int main (void) {dwV-qz  
{ <@A^C$g  
 return 0; 3EvA 5K.  
} 1I`D$Xq~:  
Em,!=v(*  
%&XX*& q  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: IT(c'}  
bwJi[xF  
class TestUnion }'W^Ki$  
{ {Y[D!W2y  
 public: l.x }I"tf  
 int data_; q,DX{:  
}; IJ8DN@w9  
xgz87d/<:  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! 4AYc 8Z#'  
i!3KG|V  
二、类中union的初始化 FW DuH`-5  
x]oQl^ F  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: v8Zg og)V  
`5Btg. &  
#pragma warning(disable : 4786) !5j3gr ~  
#include -y?Z}5-rs  
R3n&o%$*  
using namespace std; <6C9R>  
nY9qYFw  
class TestUnion w<Cmzkf  
{ u;Eu<jU1  
enum StoreType{Long,Const_CharP}; $>=Nb~t!/  
union Y:%)cUxA  
{ Wk?|BR]O  
const char* ch_; {*;]I?9Al  
long l_; OLNn3 J  
} data_; ?d<:V.1U@  
StoreType stype_; nn L$m_K~  
TestUnion(TestUnion&); AvE^ F1  
TestUnion& operator=(const TestUnion&); jF{gDK  
public: xm|4\H&Bg  
TestUnion(const char* ch); 3:joSQa  
TestUnion(long l); YeC,@d[  
operator const char*() const {return data_.ch_;} _(`X .D  
operator long() const {return data_.l_;} &ORv bnd6  
}; Y-q@~v Z]  
R+K&<Rz  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) f WjS)  
{ v^W?o}W  
} &JhIn%=-  
CY3\:D0I  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) {Okik}Oh  
{ HwW[M[qA  
} v?D kDnta  
7e4tUAiuU  
int main (void) 2${,%8"0s  
{ h0 GdFWN  
TestUnion pszobj("yuankai"); }gi1?a59  
TestUnion lobj(1234);  K-5"#  
cout<(pszobj)< cout<  ,eeL5V  
return 0; KPjqw{gR_R  
} 3cfZ!E~^kc  
|g\.5IM#W  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: nhP~jJn  
W|H4i;u  
class TestUnion ;8L+_YCa  
{ I6hhU;)C  
enum StoreType{Long,Const_CharP}; p#;dLM/EA  
union DataUnion //不能匿名 h"BhTx7E}  
{ 1Fvv/Tj  
DataUnion(const char*); //声明const char*构造函数 bm tJU3Rm  
DataUnion(long); //声明long构造函数 >OKS/(I0  
const char* ch_; krr-ZiK  
long l_; ZaRr2Z:!  
} data_; p~, 3A:i  
StoreType stype_; -Ty<9(~S  
TestUnion(TestUnion&); /md Q(Dm  
TestUnion& operator=(const TestUnion&); .}$`+h8W T  
public: nXM9Px!  
TestUnion(const char* ch); MOp=9d+N~  
TestUnion(long l); A| gs Uh  
operator const char*() const {return data_.ch_;} OP|.I._I  
operator long() const {return data_.l_;} iC\rhHKQ  
}; )~?S0]j}  
tv@Z 5  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) Y uw E 0  
{//注意data_(ch),这里直接引用data_ 5&n988g C8  
} hpqHllL  
Bt*&L[&57  
TestUnion::TestUnion(long l):data_(l),stype_(Long) _cxm}*}\#  
{//注意data_(l),这里直接引用data_ U9@t?j_#X{  
} Jm]]>K8.3V  
, `[Z`SUk`  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) kH>vD = q>  
{ P;L)1 g  
} -~( 0O  
2rR@2Vsw2  
TestUnion::DataUnion::DataUnion(long l):l_(l) e-%7F]e  
{ )T.pjl  
} q19k<BqR  
=A0"0D{\  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
如果您在写长篇帖子又不马上发表,建议存为草稿
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八