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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 ST*h{:u&A  
gF{ehU%  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 S/'0czDMW  
a;HAuy`M x  
  一、在union中存储对象 E 5&Z={  
:(n<c  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? I}4 PB+yu  
=Z^5'h~  
#pragma warning(disable : 4786) Y@+Rb  
#include ;5j|B|v  
using namespace std; %":3xj'EEI  
IL].!9  
class TestUnion _uQ]I^'D  
{ 1INX#qTZ  
 public: z'q~%1t  
 TestUnion(long l):data_(l) OIrm9D #  
 { kv:9Fm\$  
  }; ENTcTrTn  
 int data_;  ,&hv x  
}; V.GM$  
!=dz^f.{  
typedef union _tagUtype_ $o[-xNn1  
{ iHD!v7d7  
 TestUnion obj; 2LwJ%!  
}UT; ]@&X*~c^Z  
DKIH{:L7  
int main (void) Ei4^__g\'  
{ <7^|@L 6  
 return 0; ic2 D$`M  
} u&:N`f  
= l`)b  
y(COB6r  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: Pd91<L  
z#tIa  
class TestUnion iq; | i!  
{ C*Vm}|)  
 public: {D4FYr J  
 int data_; {*yvvb  
}; 0JlNUO5Nt  
9-42A7g^C  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! F9r.DG$}  
&6x(%o|  
二、类中union的初始化 g*V.u]U!i  
(T%F^s5D  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: 1q}L O2  
V:n0BlZ,B  
#pragma warning(disable : 4786) a"vzC$Hxd  
#include Lw>B:3e  
[6!k:-t+  
using namespace std; $Rm~ VwY#  
Fw<"]*iu  
class TestUnion @Q74  
{ *S;}&VAZ  
enum StoreType{Long,Const_CharP}; 7V"?o  
union W'./p"2g  
{ @>8(f#S%  
const char* ch_; 7Nq< o5  
long l_; >tM4|w|  
} data_; @;/Pl>$|'G  
StoreType stype_; \ "O5li3n  
TestUnion(TestUnion&); X=sE1RB  
TestUnion& operator=(const TestUnion&); >XgoN\w  
public: ]rG=\>U3~  
TestUnion(const char* ch); {T4_Xn-I  
TestUnion(long l); /@9Q:'P  
operator const char*() const {return data_.ch_;} 7 Lm9I  
operator long() const {return data_.l_;} :5k* kx#y  
}; q[$>\Nfg>B  
=3bk=vy  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) ;8]HCC@:  
{ |;gx;qp4cN  
} EG{+Sz  
n`5Nf  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) B"43o7C  
{ x"2p5T7*>  
} _^<vp  
Cd%5XD^  
int main (void) , 'pYR]3  
{ tiK M+ ;C  
TestUnion pszobj("yuankai"); bQaRl=:[:  
TestUnion lobj(1234); Jq_\r' YE  
cout<(pszobj)< cout< S@,/$L  
return 0; B7\4^6Tx  
} P27Ot1px  
.}dLqw  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: o-<i+To%  
yhH2b:nY(9  
class TestUnion uX7L1~s-  
{ c~T {;  
enum StoreType{Long,Const_CharP}; :w^:Z$-hf  
union DataUnion //不能匿名 Q7+WV`&  
{ KMhrw s{&B  
DataUnion(const char*); //声明const char*构造函数 7ZUN;mr  
DataUnion(long); //声明long构造函数 0F$|`v"0  
const char* ch_; | R,dsBd  
long l_; RZz?_1'  
} data_; Il =6t  
StoreType stype_; 2"6L\8hd2  
TestUnion(TestUnion&); >{^_]phlb  
TestUnion& operator=(const TestUnion&); QytO0K5  
public: neEqw +#Z  
TestUnion(const char* ch); BVal U  
TestUnion(long l); X_PzK'#m  
operator const char*() const {return data_.ch_;} DwBe_h.  
operator long() const {return data_.l_;} OS[ s Qo5  
}; 2f(`HSC'  
f} c;s  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) `q}D#0  
{//注意data_(ch),这里直接引用data_ LW=qX%o{  
} SqAz((  
nDkG}Jk B!  
TestUnion::TestUnion(long l):data_(l),stype_(Long) (Q{JI~P  
{//注意data_(l),这里直接引用data_ 5H._Q  
} 6C$+D  
@5Z|e  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) {V[xBL <  
{ |]kiH^Ap  
} U`*we43  
_kD5pC =  
TestUnion::DataUnion::DataUnion(long l):l_(l) lg|6~=aQ  
{ X "Eqhl<t  
} SrA6}kS  
as:=QMV  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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