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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 Snm m (.  
O3H~|R+^  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 0#K?SuY.eN  
jkz .qo-%  
  一、在union中存储对象 +C`h*%BW  
Grot3a  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? :-Gf GL>]  
a;},y|'E  
#pragma warning(disable : 4786) 879x(JII  
#include e+Qq a4  
using namespace std; '3B\I#  
cY&SKV#  
class TestUnion /{|<3CEe  
{ EvA{@g4>  
 public: 0MV^-M   
 TestUnion(long l):data_(l) 3I|&}+Z6  
 { O3U6"{yJ)  
  }; : z=C   
 int data_; ^Rgm3?7  
}; "S#}iYp  
^Kvbpi,  
typedef union _tagUtype_ :`FL95  
{ iF.eBL%  
 TestUnion obj; /]0-|Kg+R  
}UT; )HLe8:PG~  
?`& l Y  
int main (void) M]\p9p(_  
{ .uu[f2.N+  
 return 0; P F#X8+&J  
} (``EBEn  
-N'xQ(#n3q  
bf~gWzA  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: m(~5X0  
\W"N{N  
class TestUnion qs$%/  
{ < 0S+[7S"  
 public: jt({@;sU[<  
 int data_; q(tdBd'o6  
}; () l#}H`m  
\>8r)xC  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! .#py5&`%  
MjGeH>c  
二、类中union的初始化 ["5Z =4  
fpj,~+  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: QfLDyJv`e  
&4g]#A>@  
#pragma warning(disable : 4786) !8cS1(a  
#include H l'za  
<IiX_*  
using namespace std; f 7g?{M  
'|v??`o#  
class TestUnion .f+ul@o  
{ tS$^k)ZXip  
enum StoreType{Long,Const_CharP}; O\=U'6 @  
union pn},ovR;  
{ "O`{QVg:  
const char* ch_; AsBep  
long l_; 94 2(a  
} data_; Ww8C}2g3  
StoreType stype_; 5C03)Go3Z  
TestUnion(TestUnion&); "rV-D1Dki  
TestUnion& operator=(const TestUnion&); YMlnC7?_ /  
public: f:/[  
TestUnion(const char* ch); q7itznQSKc  
TestUnion(long l); sbWen?  
operator const char*() const {return data_.ch_;} BvXA9YQ3  
operator long() const {return data_.l_;} D1Yc_  
}; y)`f$Hl@1  
-2)6QKh~D  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) O26'|w@$  
{ ]_8bX}_n  
} u`%Kh_  
(A\X+S(  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 2WKYf0t  
{ 0+a-l[!p  
} ;<aT| 4  
Zd2B4~V  
int main (void) Mqy5>f)  
{ |sQC:y>  
TestUnion pszobj("yuankai"); %'}zr>tx:  
TestUnion lobj(1234); hJuR,NP  
cout<(pszobj)< cout< \KBE+yj  
return 0; ~/R,oQ1!g}  
} O'<5PwhG  
{km~,]N  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: ^/K]id7 2  
p2v+sWO  
class TestUnion c ilo8x`  
{ ){XaO;k<]  
enum StoreType{Long,Const_CharP}; zv1#PfO@)  
union DataUnion //不能匿名 5PaOa8=2f  
{ \0K3TMl)J  
DataUnion(const char*); //声明const char*构造函数 S4r-s;U-v/  
DataUnion(long); //声明long构造函数 +<\)b(  
const char* ch_; `v]|x,l+C  
long l_; yvPcD5s5  
} data_; 4 _*^~w  
StoreType stype_; !B&OK&*  
TestUnion(TestUnion&); M Y2=lT  
TestUnion& operator=(const TestUnion&); {FIr|R&  
public: z.NJu q  
TestUnion(const char* ch); YQ\c0XG  
TestUnion(long l); DEdJH4  
operator const char*() const {return data_.ch_;} J}$St|1y  
operator long() const {return data_.l_;} &#keI.,  
};  j|Q*L<J  
aFCma2  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) SN${cs%  
{//注意data_(ch),这里直接引用data_ C}i1)   
} 0QWc1L  
~1_v;LhH5+  
TestUnion::TestUnion(long l):data_(l),stype_(Long) 29W~<E8K-  
{//注意data_(l),这里直接引用data_ Dz<"eyB\  
} ;y"=3-=vM"  
q_5hKipd\b  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) hKG)* Q  
{ =/ b2e\  
} -E*VF{IG1  
kOu C@~,  
TestUnion::DataUnion::DataUnion(long l):l_(l) \`FpBE_e)  
{ I}?+>cf  
} 5_|Sm=  
XZ|%9#6  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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