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

C++中union的应用剖析

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
前言 XIl#0-E0X  
w7vQ6jkH  
  熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 A.r.tf}:  
m2ph8KC  
  一、在union中存储对象 O(_f&a  
:?i,!0#"  
  在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? F*N Hy.Y  
(/t{z =  
#pragma warning(disable : 4786) fWDTP|DV  
#include gT,iH.  
using namespace std; r]wy-GT  
-OKXfN]  
class TestUnion U<'z, Px6  
{ IA}.{zY~|  
 public: Kf)$/W4  
 TestUnion(long l):data_(l) n^l5M^.  
 { `q1-yH0~4  
  }; #sbW^Q'I  
 int data_; %L-{4Z!"sI  
}; w[EEA_\  
n-<`Z NMU  
typedef union _tagUtype_ T~p>Ed9  
{ NvpDi&i  
 TestUnion obj; A v;NQt8ut  
}UT; 1 7 iw`@  
%uo#<Ny/ I  
int main (void) c^5fhmlt  
{ twaH20  
 return 0; !!Yf>0u#  
} Q2Uk0:M  
F>%,}Y~B:  
2<V`  
  这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: gx C`Ml  
:z|$K^)7Z  
class TestUnion <N=ow"rD  
{ Z hCjY  
 public: )_?HBTG  
 int data_; `H^ H#W  
}; j2 >WHh  
m]{/5L  
  再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! ^lK!tOeO  
yC!>7@m  
二、类中union的初始化 p-7?S^!l  
x'%vL",%  
  由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下:  8*uaI7;*  
yDpv+6(a  
#pragma warning(disable : 4786) t6)R 37  
#include 1Eryw~,,9i  
a<((\c_8G  
using namespace std; *;lb<uLv  
q'X#F8v  
class TestUnion RGY#0.Z}  
{ 5\ }QOL  
enum StoreType{Long,Const_CharP}; (F:|tiV+  
union !wro7ilMB  
{ ma`sv<f4-!  
const char* ch_; _~*ba+{  
long l_; Vu<mOuh  
} data_; OSC_-[b-  
StoreType stype_; Fg2/rC:_  
TestUnion(TestUnion&); cn9=wm\\  
TestUnion& operator=(const TestUnion&); E6-~  
public: |I.5]r-EK  
TestUnion(const char* ch); GB6(WAmr  
TestUnion(long l); -, $:^4  
operator const char*() const {return data_.ch_;} oiz]Bd  
operator long() const {return data_.l_;} 1Va@w  
}; li} >xDSQ4  
*r6v9  
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) /5\{(=0  
{ Prv=f@  
} +bWo{   
JNu+e#.Y  
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) nyG5sWMpe  
{ ~6Odw GWV  
} ~AF' 6"A  
1}CJ&  
int main (void) u:^9ZQ+  
{ j?! /#'  
TestUnion pszobj("yuankai"); q+XU Cnv  
TestUnion lobj(1234); X8XE_VtP  
cout<(pszobj)< cout< 2nSz0 .  
return 0; 1flBA,6L  
} 6(q8y(.`  
fs#9*<]m  
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: P;ZVv{mT  
j<L!(6B  
class TestUnion +# @2,  
{ U(<~("ocN  
enum StoreType{Long,Const_CharP}; xp"F)6  
union DataUnion //不能匿名 H.[(`wi!I  
{ pJQ_G`E  
DataUnion(const char*); //声明const char*构造函数  w4UJXc  
DataUnion(long); //声明long构造函数 u>2opI~m  
const char* ch_; yJ8_<A  
long l_; 9}d^ll&  
} data_; 2o0WS~}5  
StoreType stype_; S Fqq(K2u  
TestUnion(TestUnion&); 9['>$ON  
TestUnion& operator=(const TestUnion&); 1Msc:7:L  
public: 3 gW+|3E  
TestUnion(const char* ch); 2(Nf$?U @0  
TestUnion(long l); ;^8X(R  
operator const char*() const {return data_.ch_;} ,B,0o*qc{K  
operator long() const {return data_.l_;} ,u.A[{@py  
}; !\q'{x5C  
Acb %)Y  
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) OX.g~M ig|  
{//注意data_(ch),这里直接引用data_ ?"p.Gy)  
} Dh9C9<Ta:  
s>ZlW:jY  
TestUnion::TestUnion(long l):data_(l),stype_(Long) XeAH.i<  
{//注意data_(l),这里直接引用data_ rX|{nb  
} W!a'KI'  
FOuPj+}F  
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) 1_)Y{3L  
{ |eej}G(,m}  
} ^O3p:X4u  
|b|bL 7nx  
TestUnion::DataUnion::DataUnion(long l):l_(l) U+@rLQ.-  
{ *47%| bf`  
} +3-f$/po  
S$nEflcz  
  现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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