문제

I'm relatively new to C++ and I'm wondering if structs are copied in the following case:

struct foo {
  int i;
  std::vector<int> bar;
}

class Foobar {
  foo m_foo;

  void store(foo& f) {
    this->m_foo = f;
  }
}

void main() {
  Foobar foobar;
  {
    foo f;
    f.i = 1;
    f.bar.insert(2);
    foobar.store(f);
  }
  // will a copy of f still exist in foobar.m_foo, or am I storing a NULL-Pointer at this point?
}

The reason why I am asking this is that I am originally a .NET developer and in .NET structures will be copied if you pass them to a function (and classes are not). I'm pretty sure it would be copied if store was not declared to take f by reference, but I cannot change this code.

Edit: Updated the code, because I didn't know that the vector.insert would affect my question. In my case I store the struct as a member in a class, not a vector. So my question really was: will f be copied at this->m_foo = f;?

도움이 되었습니까?

해결책

Short answer: Yes.

Long answer: You'd have to get a pointer to a stack allocated struct and then let that struct go out of scope in order to end up with a dangling reference in your vector... but even then, you wouldn't have stored a NULL. C and C++ pointers are simple things, and will continue to point at a memory location long after that memory location has become invalid, if your code doesn't overwrite them.

It might also be worth noting that std::vector has a decent set of copy and move functions associated with it that will be called implicitly in this case, so the bar vector inside the struct will also be copied along with the simple integer i. Standard library classes tend to be quite well written, but code by other folk has no such guarantee!

Now, as regards your edit:

class Foobar {
  foo m_foo;

 void store(foo& f) {
    this->m_foo = f;
  }
}

You will still not have any problems with the foo instance stored in m_foo. This is because this->m_foo = f invokes a copying operation, as m_foo is not a variable of a reference or pointer type. If you had this instead: foo& m_foo then you would run into difficulties because instead of copying a foo instance you are instead copying a reference to a foo instance, and when that instance goes out of scope, the reference is no longer valid.

다른 팁

Yes, the struct will be copied, in the following function:

foos.insert(f);

As a copy is made, you won't be storing a null pointer / null reference.

However, like you've said, it won't be copied when you call store(f); as the function accepts the argument as a reference.

Your edit will still make a copy of Foo. You are assigning one instance of a variable to another instance of a variable. What you aren't doing is assigning one pointer (reference in C#) to another. You could probably do with doing some reading around C++ object instances, pointers, and references.

A copy of f is made during foos.insert(f)

void store(foo& f) {
  foos.insert(f);
}

void main() {
  {
    foo f;
    f.i = 1;
    f.bar.insert(2);
    store(f);
  }
  // at this place, local variable `f` runs out of scope, it's destroyed and cleaned up
  // foos is holding the copy of `f`
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top