Я относительно новичок в 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;
?
Краткий ответ: да.
Длинный ответ: вам нужно будет получить указатель на структуру, выделенную из стека, а затем позволить этой структуре выйти из области видимости, чтобы в конечном итоге получить висячую ссылку в вашем векторе … но даже тогда вы бы не сохранили 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
экземпляр, и когда этот экземпляр выходит из области видимости, ссылка больше не действительна.
Да, структура будет скопирована в следующую функцию:
foos.insert(f);
Когда копия сделана, вы не будете хранить нулевой указатель / нулевую ссылку.
Однако, как вы сказали, это не будет копировать при звонке store(f);
так как функция принимает аргумент в качестве ссылки.
Ваше редактирование все равно сделает копию Foo. Вы присваиваете один экземпляр переменной другому экземпляру переменной. Что ты не делать это присваивать один указатель (ссылка в C #) на другой. Возможно, вы могли бы заняться чтением вокруг экземпляров объектов C ++, указателей и ссылок.
Копия 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`
}