前言 k.Gt}\6zP
O U9{Y9e
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。
j0O1??
AW9%E/{
一、在union中存储对象 <7B;_3/
3m2y<l<
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? M9Yov4k,4]
s|Vs#o.P)
#pragma warning(disable : 4786) s?nj@:4
#include K|6}g7&X
using namespace std; s>WqVuXmn
TaKHr$h
class TestUnion hp}rCy|01
{ IM[=]j.?
public: i=M[$
TestUnion(long l):data_(l) )=aqj@v
{ E%stFyr9`/
}; XRyeEwA;pp
int data_; s k~7"v{Y.
}; W=|'&UU Ul
IBNb!mPu%
typedef union _tagUtype_ L;b-=mF
{ v]KPA.W
TestUnion obj; F^TOLwix
}UT; @cm[]]f'l
>Yv#t.!
int main (void) R_Bf JD.
{ BP4vOZ0$
return 0; *]k E3
} `$3P@SO"
tEibxE
=U:]x'g(
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: xcJvXp
Esg:
class TestUnion +l7Bu} _?
{ x0TE+rf5
public: OU mZ|
int data_; Th~pju
}; v yP_qG
*t={9h
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! f\~w!-
Rob:W|
二、类中union的初始化 ~ r$I&8
f9n4/(Cy
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: nXxnyom,
)S_%Ip
#pragma warning(disable : 4786) :4COPUBpPV
#include ^4saB+qm
`X`|]mWj
using namespace std; #e9XU:9@g
P|aSbsk:I<
class TestUnion I+Fr#1
{ `]Vn[^?D
enum StoreType{Long,Const_CharP}; x6=tS
union 0E&XD&D
{ qEjsAL
const char* ch_; uQWd`7
long l_; wp-3U}P2(
} data_; |e3YTLsI
StoreType stype_; qv/chD`C
TestUnion(TestUnion&); +6Vu]96=KC
TestUnion& operator=(const TestUnion&); "n<u(m8E
public: +Pn`AV1
TestUnion(const char* ch); H329P*P
TestUnion(long l); .:, 9Tf
operator const char*() const {return data_.ch_;} Fd9Z7C
operator long() const {return data_.l_;} ra\|c>[%
}; 'wTJX>
Lismo#
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) 0+S'i82=M
{ zU};|Zw
} ;{cl*EN
v8A{q
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 2wgdrO|B
{ vYG$>*
} g|4v>5Y
:SpPT
int main (void) XecU&
{ w~*"mZaG
TestUnion pszobj("yuankai"); %!)Dk<
TestUnion lobj(1234); rHgrCMW
cout<(pszobj)< cout< vy F(k3W
return 0; ^KFwO=I@PV
} {pB9T3ry]
Bk~M ^AK@~
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: HLM"dmI
{{_,YO^w
class TestUnion :~9F/Jx
{ q0
8
enum StoreType{Long,Const_CharP}; w+tO@
union DataUnion //不能匿名 iD9hqiX&
{ \t@|-`
DataUnion(const char*); //声明const char*构造函数 ~#
|p=Y
DataUnion(long); //声明long构造函数 KHXnB
const char* ch_; Mxe
long l_; r7p>`>_Q\
} data_; yh Ymbu
StoreType stype_; Y~M H
TestUnion(TestUnion&); l,3[hx
TestUnion& operator=(const TestUnion&); c}FZb$q#
public: x;R9Gc[5
TestUnion(const char* ch); _&m
TestUnion(long l); I^6zUVH
operator const char*() const {return data_.ch_;} ~UJ_Rr54
operator long() const {return data_.l_;} _/!IjB:(70
}; c
=i6
/1lUFL2D
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) oMi"X"C:q
{//注意data_(ch),这里直接引用data_ XX(;,[(_
} z<mU$<
<kmn3w,vi
TestUnion::TestUnion(long l):data_(l),stype_(Long) hw&R.F
{//注意data_(l),这里直接引用data_ ^T|~L<A3
} g< {jgF
Ofg-gCF8
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) ?o9g5Z
{ [nlW}1)46
} &u_f:Pog
SpY%2Y.Dy
TestUnion::DataUnion::DataUnion(long l):l_(l) O(PG"c
{ /^\6q"'
} &a
p{|>3
RW|3d<Fj
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!