前言 XSZ k%_
yiA<,!;4P
熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。 ,xx R\}
}O4^Cc6
一、在union中存储对象 `9b7>Nn<
fP `b>]N_
在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗? 1N>|yQz
aUtnR<6
#pragma warning(disable : 4786) uF3qD|I\
#include IyLx0[:U
using namespace std; @$+ecaVW
qhz]Wm P
class TestUnion Z LD}a:s
{ >:|q&|x-
public: <|Pun8j
TestUnion(long l):data_(l) bAm(8nT7w
{ EB8\_]6XJ
}; ;y2/-tL?
int data_; d:U9pC$
}; [`):s= FC
GHeVp/u
typedef union _tagUtype_ `WH"%V:"Q
{ .8G@%p{,
TestUnion obj; ,5*eX
}UT; _\GC(
=Fr(9(
int main (void) )6J9J+%bi
{ ])!o5`ltZ
return 0; a0ObBe'
} Aj4T"^fv
UTH_^HAN#G
Sh8"F@P8
这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改: "
_ka<R..
}-6)gWe
class TestUnion vt9)pMs
{ +qwjbA+
public: L-k@-)98
int data_; TTTPxO,
}; ?CA,
8Bjib&im
再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的,我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧! 9*1,!%]
ML>[^F
二、类中union的初始化 W!>.$4Q9
u[
Yk
由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下: 6gs01c,BA
|]X
#pragma warning(disable : 4786) k<\$OoOZ
#include &E=>Hj(dTG
SrK) t.oK
using namespace std; 8{X"h#
N/K.%<h
class TestUnion 9B7^lR
{ SV~~Q_U9
enum StoreType{Long,Const_CharP}; Aw5HF34J
union
S :<Nc{C
{ Gnq?"</
const char* ch_; }=]M2}
long l_; {R?U.eJW
} data_; tyqT
StoreType stype_; e!=kWc
TestUnion(TestUnion&); 4Q6mo/=H
TestUnion& operator=(const TestUnion&); d*%`!G
public: &?yZv{
TestUnion(const char* ch); VQS~\:1
TestUnion(long l); I\$X/t +dH
operator const char*() const {return data_.ch_;} cbT7CG
operator long() const {return data_.l_;} Tap.5jHL
}; #a8B/-
VN\W]jT
TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP) (j3xAA
{ suzZdkMA
} 65aK2MS@
%YC_Se7
TestUnion::TestUnion(long l):data_.l_(l),stype_(Long) 1BpiV-]=
{ [CXrSST")E
} ?3.b{Cq{-
j?x>_#tIY
int main (void) ]33>m|?@
{ ^>hW y D
TestUnion pszobj("yuankai"); lUvpszH=
TestUnion lobj(1234); )j0TeE1R
cout<(pszobj)< cout< TO?R({yx*
return 0; 7OJ'){R$
} Gf<'WQ[
ikvWh<=>H
真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下: #nPQ!NB/
zIu
E9l
class TestUnion
7B\Vs-d
{ a+Kj1ix
enum StoreType{Long,Const_CharP};
`yH<E+
union DataUnion //不能匿名 tAv@R&W,
{ e(GP^oK
DataUnion(const char*); //声明const char*构造函数 mSb#Nn6W
DataUnion(long); //声明long构造函数 Ke2ccN
const char* ch_; \Yc'~2n
long l_; 0,89H4
} data_; V#S9H!hm$
StoreType stype_; E(8*
pI
TestUnion(TestUnion&); m;GbLncA
TestUnion& operator=(const TestUnion&); 8)10o,#L
public: rFj-kojg
TestUnion(const char* ch); ,l:ORoND
TestUnion(long l); t7j);W%e6
operator const char*() const {return data_.ch_;} +oovx2r&
operator long() const {return data_.l_;} #x 177I\
}; ASk|A!
|n,<1QY
TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP) iA' lon
{//注意data_(ch),这里直接引用data_ y+c|vdW%
} -v]Sr33L
6'!4jh
TestUnion::TestUnion(long l):data_(l),stype_(Long) HiR[(5vnf
{//注意data_(l),这里直接引用data_ {^7Hgg
} 5BlR1*
,>0* @2
TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch) eQp4|rf
{ KmA;HiH%J
} yl7&5)b#9
0c<.iM
TestUnion::DataUnion::DataUnion(long l):l_(l) d\R,Q
{ %)/P^9I6
} ;kS&A(
~&7MkkftM
现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!