background image

配操作,或者其它对整个 application 状态的修改,那么,如果我今后要用到 obj 的话,事
情可能还比较合理,但是如果我根本就不使用 obj 这个成员呢?由于 obj 的引入造成的对
系统状态的修改显然是不合理的;反之,如果答案是 no,那么一旦我们今后选中了 obj 来
进行操作,则所有信息都没有初始化(如果是普通的 struct,没什么问题,但是,如果有
虚函数呢?)。更进一步,假设现在我们的 union 不是只有一个 TestUnion obj,还有一个
TestUnion2 obj2,二者均有构造函数,并且都在构造函数中执行了一些内存分配的工作
(甚至干了很多其它事情),那么,如果先构造 obj,后构造 obj2,则执行的结果几乎可以
肯定会造成内存的泄漏。

  鉴于以上诸多麻烦(可能还有更多麻烦),在构造 union 时,编译器只负责分配空间,
而不负责去执行附加的初始化工作,为了简化工作,只要我们提供了构造函数,就会收
到上面的 error。
同理,除了不能加构造函数,析构函数/拷贝构造函数/赋值运算符也是不可以加。

  此外,如果我们的类中包含了任何 virtual 函数,编译时,我们将收到如下的错误信
息:
  error C2621: union ‘__unnamed‘ : member ‘obj‘ has copy constructor

  所以,打消在 union 中包含有构造函数/析构函数/拷贝构造函数/赋值运算符/虚函数
的类成员变量的念头,老老实实用你的 C 风格 struct 吧!
  不过,定义普通的成员函数是 OK 的,因为这不会使得 class 与 C 风格的 struct 有任
何本质区别,你完全可以将这样的 class 理解为一个 C 风格的 struct + n 个全局函数。

  现在,再看看在类中包含内部 union 时会有什么不同。看看下面的程序,并请注意阅
读程序提示:

  class TestUnion
  {
  union DataUnion
  {
  DataUnion(const char*);
  DataUnion(long);
  const char* ch_;
  long l_;
  } data_;

  public:
  TestUnion(const char* ch);
  TestUnion(long l);
  };

    TestUnion::TestUnion(const char* ch) : data_(ch) // if you want to use initialzing list to 
initiate a nested-union member

 

, the union must not be anonymous and must have a constructor。

  {