Мне кажется, я понимаю, чего вы пытаетесь достичь, но если цель состоит в обучении, тогда я настоятельно рекомендую вам понять, почему то, чего вы ожидаете, не происходит.Прежде чем перейти к поиску «обходного пути» для достижения того, чего вы пытаетесь достичь.
Чтобы лучше понять, это может помочь в написании упрощенного кода, демонстрирующего то же поведение.То, что вы написали, более или менее эквивалентно:
struct A {
int childCount = 0;
};
int main() {
A a1;
std::vector<A> vecA{a1};
a1.childCount = 1;
std::cout << vecA[0].childCount<< "\n"; // What do you expect here?
}
, что эквивалентно:
A a1;
A copyOfA1 = a1;
a1.childCount= 1;
std::cout << copyOfA1.childCount << "\n"; // What do you expect here?
, что эквивалентно:
int a1 = 0;
int copyOfA1 = a1;
a1 = 1;
std::cout << copyOfA1 << "\n"; // What about here?
a0
содержит отдельную копию из a1
, а не ссылку на a1
, поэтому, если вы сделаете изменение в оригинале a1
, копия a1
, хранящаяся в a0
, не будетизменить.
РЕДАКТИРОВАТЬ : Что касается того, как достичь того, чего вы хотите достичь.Я предполагаю, что A
не должен владеть своими детьми.Вы хотите, чтобы он содержал не принадлежащие ссылки на A
s, которые хранятся в другом месте.К сожалению, std::vector
не может содержать ссылку на C ++.std::vector
может содержать необработанный указатель, но вы специально попросили не использовать необработанные указатели.
Альтернативой является std::reference_wrapper<A>
, который немного напоминает ссылку на C ++.но присваивается, чтобы его можно было использовать в std::vector
.Вы можете скрыть std::reference_wrapper
, предоставив функцию-член для доступа к дочернему элементу по индексу:
#include <iostream>
#include <vector>
#include <functional>
struct A {
int id;
A(int id_):id(id_){}
std::vector<std::reference_wrapper<A>> childs;
A& at(size_t index) { return childs[index]; }
};
int main()
{
A a0(0), a1(1);
a0.childs={a1};
a1.childs={a0};
std::cout << a0.childs.size() << "\n";
std::cout << a1.childs.size() << "\n";
std::cout << a0.at(0).childs.size() << "\n";
}
Демонстрационная версия .
Но, чтобы быть понятным,std::reference_wrapper
- это просто оболочка необработанного указателя, вы должны убедиться, что объект, на который он указывает, все еще жив.
Edit2 : По запросу, вотверсия, которая использует вектор необработанных указателей:
#include <iostream>
#include <vector>
struct A {
int id;
A(int id_):id(id_){}
std::vector<A*> childs;
A& at(size_t index) { return *childs[index]; }
};
int main()
{
A a0(0), a1(1);
a0.childs={&a1};
a1.childs={&a0};
std::cout << a0.childs.size() << "\n";
std::cout << a1.childs.size() << "\n";
std::cout << a0.at(0).childs.size() << "\n";
}
Демо-версия .
Обратите внимание, что вы должны взять адрес a1
, используя &
, когдаинициализация вектора.