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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 aI%g2 q0f  
r(6Y*<  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 6w*dKInG[-  
x/NfZ5e0X  
  一、在union中存储对象 O(#)m>A  
EOIN^4V"  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? cbNTj$'b2u  
F5LuSy+v  
#pragma warning(disable : 4786) fX(3H1$"  
#include {'N Z.  
using namespace std; ls_'')yp  
O_2pIbh  
class TestUnion BHIRH mM<Y  
{ Lco~,OE  
 public: ~d o9;8v  
 TestUnion(long l):data_(l) TCN8a/@z  
 { SAH-p*.  
  }; cpe+XvBuK  
 int data_; ZXu>,Jy  
}; Y4OPEo5o  
H7?Vybg~  
typedef union _tagUtype_ ++bf#qS<8D  
{ v6[!o<@"a  
 TestUnion obj; c%^7!FSg  
}UT; 8{|8G-Mi  
0Be< X  
int main (void) )s)I2Z+  
{ 6|K5!2  
 return 0; d:_t-ZZo  
} 0m7Y>0wC6T  
S(o#K|)>  
9?A)n4b;  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: k o5@qNq  
#Z}Rf k(~  
class TestUnion ) mI05  
{ 45=bGf#  
 public: r  [9x  
 int data_; dl.N.P7}4  
}; dah[:rP,n{  
mH54ja2  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! }wWKFX  
-<c=US  
二、类中union的初始化 jTf@l?|  
CHdX;'`*  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: aC^\(wp[  
heltgRt  
#pragma warning(disable : 4786) )bA;?i  
#include Bt[/0>i  
\@-@Y  
using namespace std; kJWn<5%ayg  
K}2Erm%A@y  
class TestUnion ^aIPN5CK  
{ qBU-~"2t  
enum StoreType{Long,Const_CharP}; ~ {?_p@&n  
union /Y*WBTV'  
{ 7@#>b E6  
const char* ch_; 4]rnY~  
long l_; pny11C  
} data_; ylUrLQ\  
StoreType stype_; #ml S}~n  
TestUnion(TestUnion&); Hh%I0#  
TestUnion& operator=(const TestUnion&); Jx_cf9{  
public: _G_Cj{w  
TestUnion(const char* ch); lackB2J9 A  
TestUnion(long l); R7]l{2V#^  
operator const char*() const {return data_.ch_;} TSA,WP\  
operator long() const {return data_.l_;} =31"fS@  
}; { .n"Z  
V @rI`~$  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) %`k6w3qI  
{ [l:x'_y  
} VJ84?b{c W  
y9_V  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) ~aw.(A?MI  
{ Dw|}9;5:A  
} ioa U*%  
OHv[#xGuV?  
int main (void) 1ofKt=|=  
{ |o,YCzy|5  
TestUnion pszobj("yuankai"); s|@6S8E  
TestUnion lobj(1234); -)s qc P  
cout<(pszobj)< cout< c@YI;HS_g  
return 0; gep;{G}  
} g6nkZyw  
du+y5dw  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: k2E0/ @f{k  
zFfoqb#*g  
class TestUnion 5&xB6|k  
{ =6xrfDbN8  
enum StoreType{Long,Const_CharP}; &6DMk-  
union DataUnion //不能匿名 1h(0IjG8  
{ ?xK8#  
DataUnion(const char*); //声明const char*构造函数 1m+p;T$  
DataUnion(long); //声明long构造函数 X"MB|N y  
const char* ch_; so^lb?g  
long l_; >82@Q^O  
} data_; WJ)z6m]  
StoreType stype_; w'L\?pI  
TestUnion(TestUnion&); ~L]|?d"  
TestUnion& operator=(const TestUnion&); |].pDwgt  
public: \ Fl+\?~D  
TestUnion(const char* ch); h"lX 4  
TestUnion(long l); KgV3j]d  
operator const char*() const {return data_.ch_;} u,F nAh?"  
operator long() const {return data_.l_;} 2*rH?dz8E  
}; >O1[:%Z1  
IOTR/anu  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) I6~pV@h^=  
{//注意data_(ch),这里直接引用data_ ~0?mBy!-O  
} Xsa2(-  
0YaA`  
TestUnion::TestUnion(long l):data_(l),stype_(Long) k $M]3}$U  
{//注意data_(l),这里直接引用data_ h a|C&G  
} .#wqXRd  
uB |Ss  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) m_hN*v Py  
{ $`APHjijN  
} $Vsk Ew"|M  
sLh==V;9  
TestUnion::DataUnion::DataUnion(long l):l_(l) t c[n&X  
{ D@G\7 KH@  
} )64@2 ~4y  
BeCWa>54i  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
批量上传需要先选择文件,再选择上传
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八