我对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;
吗?
答案 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`
}