开发者

Questions about vector, union, and pointers in C++

开发者 https://www.devze.com 2022-12-12 02:19 出处:网络
The questions I have are NOT homework questions, but I am considering using these concepts in my assignment. The context, if it helps, is like this: I need to keep track of several union instances and

The questions I have are NOT homework questions, but I am considering using these concepts in my assignment. The context, if it helps, is like this: I need to keep track of several union instances and they belong to my own union in one of my own classes as class variables. (Note: the number of union instances is unknown, so I cannot just have a fixed number of union instances.

  1. Q1: If I have a union, say MyUnion, and many instances of this union, can I then put them into a vector like

    vector<union MyUnion> myVector(10);
    
  2. Q2: Is it valid to have a pointer of union? Like

    union MyUnion *myUnionPtr = new union myUnion;
    
  3. Q3: I am considering using a vector of union pointers in my implementation, is this concept cor开发者_JAVA技巧rect? Also, is it a normal approach in C++? Do I need to rethink about my design?


  1. If the union is CopyConstructable and Assignable, then it meets the requirements for std::vector.
    • Yes: MyUnion* ptr = new MyUnion();
    • A container of pointers works in some situations, but if you want a container of owning pointers, look at Boost's ptr_* containers. However, here it appears you'd either have a container of non-pointers or a container of non-owning pointers, either of which is fine and common for vector.

All types are, by default, both CopyConstructable and Assignable. ("Copyable" is used to mean the union of these concepts, however the standard specifies them individually.) This is because copy ctors and op= are added to classes (unions are one class-type) except under certain circumstances. There are a few references online, but I'm not aware of a single one, available freely online, that spells these out.

You have to go out of your way to prevent it, such as:

  • make the copy ctor or op= non-public
  • make the copy ctor or op= take a non-const reference
  • give the class type a non-CopyConstructable or non-Assignable member

Example:

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;
}

Note: And just because something is Copyable, doesn't mean it does what you want! Example:

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
}

The same thing holds true for unions, of course. The fix applies equally, though, as well:

struct A {
  int* p;

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

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

  ~A() { delete p; }
};

(If you spotted it, yes, A has a problem if you ever try to use op=, in just the same way as it originally had with the copy ctor.)

0

精彩评论

暂无评论...
验证码 换一张
取 消