4

我的问题不是家庭作业问题,但我正在考虑在我的作业中使用这些概念。如果有帮助,上下文是这样的:我需要跟踪几个联合实例,它们在我自己的一个类中属于我自己的联合,作为类变量。(注意:联合实例的数量是未知的,所以我不能只拥有固定数量的联合实例。

  1. Q1:如果我有一个联合,比如 MyUnion,以及这个联合的许多实例,我可以将它们放入一个向量中,比如

    vector<union MyUnion> myVector(10);
    
  2. Q2:有联合指针有效吗?像

    union MyUnion *myUnionPtr = new union myUnion;
    
  3. Q3:我正在考虑在我的实现中使用联合指针向量,这个概念是否正确?另外,它是 C++ 中的正常方法吗?我需要重新考虑我的设计吗?

4

1 回答 1

15
  1. 如果联合是 CopyConstructable 和 Assignable,那么它满足 std::vector 的要求。
    • 是的:MyUnion* ptr = new MyUnion();
    • 指针容器在某些情况下有效,但如果您想要拥有指针的容器,请查看 Boost 的ptr_* 容器。但是,在这里,您似乎要么有一个非指针容器,要么有一个非拥有指针的容器,这两种方法都适用于向量。

默认情况下,所有类型都是 CopyConstructable 和 Assignable。(“可复制”用于表示这些概念的联合,但标准单独指定它们。)这是因为除了某些情况外,复制 ctor 和 op= 被添加到类(联合是一种类类型)。网上有一些参考资料,但我不知道有哪一份可以在网上免费获得,说明这些内容。

您必须竭尽全力防止它发生,例如:

  • 使复制 ctor 或 op= 非公开
  • 使复制 ctor 或 op= 采用非常量引用
  • 给类类型一个非CopyConstructable或非Assignable成员

例子:

union CopyableUnion {
  int n;
  char c;
  double d;
};

union NonCopyableUnion {
  int n;
  char c;
  double d;

  NonCopyableUnion() {} // required, because any user-defined ctor,
  // such as the private copy ctor below, prevents the supplied
  // default ctor

private:
  NonCopyableUnion(NonCopyableUnion const&);
  NonCopyableUnion& operator=(NonCopyableUnion const&);
};

int main() {
  CopyableUnion a;
  CopyableUnion b = a; // fine, uses copy ctor
  b = a; // fine, uses op=

  NonCopyableUnion c;
  NonCopyableUnion d = c; // compile error (copy ctor)
  d = c; // compile error (op=)

  return 0;
}

注意:仅仅因为某些东西是可复制的,并不意味着它会做你想做的事!例子:

struct A {
  int* p;

  A() : p(new int()) {}

  // the provided copy ctor does this:
  //A(A const& other) : p(other.p) {}
  // which is known as "member-wise" copying

  ~A() { delete p; }
};

int main() {
  A a;
  {
    A b = a;
    assert(b.p == a.p); // this is a problem!
  } // because when 'b' is destroyed, it deletes the same pointer
  // as 'a' holds

  return 0; // and now you have Undefined Behavior when
  // ~A tries to delete it again
}

当然,工会也是如此。不过,该修复同样适用:

struct A {
  int* p;

  A() : p(new int()) {}

  A(A const& other) : p(new int(*other.p)) {}

  ~A() { delete p; }
};

(如果你发现了它,是的,如果你尝试使用 op=,A 就会出现问题,就像它最初使用复制 ctor 的方式一样。)

于 2009-11-23T21:27:18.433 回答