c++ Implicit copy of *this with std::list -
for project, have list of objects, (in illustration code, garden). each garden contains single plant, has reference garden it's in. works when making single garden, when create std::list of garden objects, re-create created somewhere don't know, , have no thought how prepare it. objects following:
struct garden; //forward declaration struct plant { plant(garden & mygarden) : thegarden(mygarden) { }; //constructor garden & thegarden; //reference garden plant in }; struct garden { garden(int size) : theplant(*this), size(size) { }; //constructor plant theplant; //plant contained in garden int size; //size of garden };
so far good. now, can create garden stand-alone, or set 1 in list. expected behaviour if alter 'size' variable, gets changed everywhere, in thegarden
. however, in list, gets changed in 'original' garden
, not in reference thegarden
int main() { //works garden onegarden(1); std::cout << "expected: 1 1, result: " << onegarden.size << " " << onegarden.theplant.thegarden.size << std::endl; onegarden.size = 2; std::cout << "expected: 2 2, result: " << onegarden.size << " " << onegarden.theplant.thegarden.size << std::endl; //does not work! std::list<garden> gardenlist; gardenlist.push_back(garden(1)); std::cout << "expected: 1 1, result: " << gardenlist.front().size << " " << gardenlist.front().theplant.thegarden.size << std::endl; gardenlist.front().size = 2; std::cout << "expected: 2 2, result: " << gardenlist.front().size << " " << gardenlist.front().theplant.thegarden.size << std::endl; homecoming 0; }
the final output following:
expected: 1 1, result: 1 1 expected: 2 2, result: 2 2 expected: 1 1, result: 1 1 expected: 2 2, result: 2 1
standard containers own elements contain. means copies made of each element when insert them.
when garden
copied, default re-create constructor used and, in turn, plant
fellow member default-copied. however, means new plant
contains reference old garden
.
in case, old garden
temporary in gardenlist.push_back(garden(1))
not not right garden
, it's garden
doesn't exist more. in short, reading size through dangling reference (which has undefined behaviour) , getting [un?]fortunate plenty see old value behind it.
you should write re-create constructor garden
copies plant
in every way except new plant
should have reference new garden
, instead of copying old reference.
the re-create , entire issue stems can avoided using new c++11 features:
gardenlist.emplace_back(1);
now, the garden
in list created in-place, , no re-create performed.
however, should still prepare underlying design problem garden
, if work around problem in way.
c++ list oop reference std
No comments:
Post a Comment