前言 W/bW=.d
Jd
BP@tI|
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 Rtz~:v%
RB+Jp
一、在union中存储对象 olv?$]
k3qQU)
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? Sp5:R75vI
wpM2{NTP
#pragma warning(disable : 4786) .g*N+T6O
#include Y 3ApW vS
using namespace std; "5V;~}=S
g4h{dFb|_
class TestUnion 2/*u$~
{ rpRyB9
public: p3U)J&]c6
TestUnion(long l):data_(l) Xk4wU$1F
{ tS2&S 6u
}; R!j #
int data_; wN!\$i@E:
}; ;0 B1P|7zK
V8M()7uJ
typedef union _tagUtype_ 8${n}}
{ e-ta 7R4
TestUnion obj; !{jw!bB
}UT; %VO+\L8Fs
#<*.{"T
int main (void) .#QE*<T)]
{ e3 v^j$
return 0; Z`tmuu
} $NVVurXa
Uqel
UL}
iM<$
n2t
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: K
";Et
n2mO-ZXud
class TestUnion >_2~uF@pb
{ D -tRy~}
public: \\dUp>1=
int data_; UDG1F_&h
}; =%m{|HQ`
8%,#TMOg
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! O t)}:oG
2=_$&oT**
二、类中union的初始化 %V>%AP
-0^]:
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: Og 1-LP|X
PuJ3#H
T
#pragma warning(disable : 4786) 8%K{l g"
#include w1tM !4r
yUnV%@.
using namespace std; 2fTuIS<yr
nB`|VYmOP1
class TestUnion 8'*x88+
{ Eiu/p&ct
enum StoreType{Long,Const_CharP}; t$$YiO
union 5?^#v
{ I;w!
const char* ch_; p-iFe\+
long l_; ye.6tlW
} data_; \8xSfe
StoreType stype_; 7su2A>Ix
TestUnion(TestUnion&); E4% -*n
TestUnion& operator=(const TestUnion&); "%Ok3Rvv
public: 4H6Fq*W{k
TestUnion(const char* ch); KM;H '~PZi
TestUnion(long l); Rt?CE jy
operator const char*() const {return data_.ch_;} <J<"`xKL
operator long() const {return data_.l_;} Yk|6?e{+)
}; qj;i03 +@
{g.YGO
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) Sh(ys*y>
{ 'd~(=6J
} AAQ!8!
$0 .6No_|
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) >T]9.`xhK
{ I$.lFQ%(
} KdkL_GSLT
i(|ug_^
int main (void) z0rYzn?MR
{ Z|C,HF+m.
TestUnion pszobj("yuankai"); +UDt2
TestUnion lobj(1234); c?CD;Pk
cout<(pszobj)< cout< =Smd/'`_
return 0; J+t51B(a
} c~tl0XU1
&j:e<{@
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: 5)< Y3nU~
%JBLp xnq
class TestUnion {LjzkXs
{ #8h7C8]&
enum StoreType{Long,Const_CharP}; \C$e+qb~{
union DataUnion //不能匿名 HK :K~h
{ UdrgUqq)
DataUnion(const char*); //声明const char*构造函数 i@+m<YS:2>
DataUnion(long); //声明long构造函数 ]D;*2Lw4&
const char* ch_; BeFyx"NBg
long l_; U Y*`R
} data_; 2n3&uvf'TL
StoreType stype_; }6^5mhsL
TestUnion(TestUnion&); ,iYhD-"'
TestUnion& operator=(const TestUnion&); q>(?Z#sB
public: 7L/LlO/
TestUnion(const char* ch); /"="y'Wx
TestUnion(long l); m$W2E.-$'#
operator const char*() const {return data_.ch_;} clyp0`,7
operator long() const {return data_.l_;} V?*fl^f
}; ):4)8@]5M
PW%ith1)<
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) &k| EG![
{//注意data_(ch),这里直接引用data_ >A]l|#Rz
} #t1? *4.p
jtfC3E,U
TestUnion::TestUnion(long l):data_(l),stype_(Long) q1YNp`]0i8
{//注意data_(l),这里直接引用data_ x])j]k
} Y
?~n6<
lMW6D0^
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) X`&Us
{ "Ltp]nCR
} jQz^)8)B
o6 NmDv5
TestUnion::DataUnion::DataUnion(long l):l_(l) ,1|=_M31
{ tjV63`LD
} 3Jda:
@o@SU"[?_
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!