C ++:将隐式复制结构

时间:2012-11-14 11:37:11

标签: c++ struct copy pass-by-reference null-pointer

我对C ++比较陌生,我想知道在以下情况下是否复制了结构:

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

我之所以这样问,原因是我原来是.NET开发人员,如果将它们传递给函数(并且没有类),将会复制.NET结构。 我很确定如果没有声明商店通过引用获取f,它将被复制,但我无法更改此代码。

修改:更新了代码,因为我不知道vector.insert会影响我的问题。在我的例子中,我将结构作为成员存储在类中,而不是向量中。 所以我的问题确实是:f会复制this->m_foo = f;吗?

3 个答案:

答案 0 :(得分:4)

简短回答:是的。

答案很长:你必须得到一个指向堆栈分配结构的指针,然后让这个结构超出范围,以便最终在你的向量中有一个悬空引用......但即便如此,你也不会已存储NULL。 C和C ++指针很简单,如果你的代码没有覆盖它们,那么在内存位置变得无效之后很久就会继续指向内存位置。

值得注意的是std::vector有一组与之关联的复制和移动函数,在这种情况下会隐式调用,因此结构中的bar向量也将是与简单整数i一起复制。标准库类往往写得很好,但是其他人的代码没有这样的保证!

现在,关于你的编辑:

class Foobar {
  foo m_foo;

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

仍然foo中存储的m_foo实例没有任何问题。这是因为this->m_foo = f调用复制操作,因为m_foo不是引用或指针类型的变量。如果您改为:foo& m_foo那么您会遇到困难,因为您不是复制foo实例,而是将引用复制到foo实例,当该实例超出范围时,引用不再有效。

答案 1 :(得分:3)

是的,将在以下函数中复制结构:

foos.insert(f);

复制完成后,您将不会存储空指针/空引用。

但是,正如您所说,当您调用store(f);时,将不会被复制,因为函数接受参数作为参考。

您的编辑仍会制作Foo的副本。您正在将一个变量实例分配给另一个变量实例。你做的是将一个指针(C#中的引用)分配给另一个。你可以做一些关于C ++对象实例,指针和引用的阅读。

答案 2 :(得分:2)

f

期间制作了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`
}