2

我对 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 结构中它们将被复制。我很确定如果 store 没有声明为通过引用获取 f ,它将被复制,但我无法更改此代码。

编辑:更新了代码,因为我不知道这vector.insert会影响我的问题。就我而言,我将结构存储为类中的成员,而不是向量。所以我的问题真的是:将f被复制this->m_foo = f;

4

3 回答 3

5

简短的回答:是的。

长答案:您必须获得一个指向堆栈分配结构的指针,然后让该结构超出范围才能在向量中得到一个悬空引用......但即使那样,您也不会存储一个NULL。C 和 C++ 指针是简单的东西,如果您的代码没有覆盖它们,那么在该内存位置变得无效后很长一段时间内,它们仍将继续指向该内存位置。

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

现在,关于您的编辑:

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.

于 2012-11-14T11:42:34.253 回答
3

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

foos.insert(f);

制作副本时,您将不会存储空指针/空引用。

但是,就像您所说的那样,当您调用时它不会被复制,store(f);因为函数接受参数作为参考。

您的编辑仍会复制 Foo. 您正在将变量的一个实例分配给变量的另一个实例。您没有做的是将一个指针(C# 中的引用)分配给另一个指针。您可能需要阅读 C++ 对象实例、指针和引用。

于 2012-11-14T11:40:16.583 回答
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`
}
于 2012-11-14T11:39:47.737 回答