Home > Net >  Creating a vector of all instances of a class when objects are being instantiated in a loop?
Creating a vector of all instances of a class when objects are being instantiated in a loop?

Time:11-29

I am trying to keep a pointer to all of the instances of a class inside of a static member variable.

#include <iostream>
#include <vector>

class Person {
public:
  static std::vector<Person*> allPeople;
  int age;
  Person(int a) {
    age = a;
    allPeople.push_back(this);
  }
};

std::vector<Person*> Person::allPeople;


int main() {
  static std::vector<Person> children;

  for(int i=0;i<10;i  ) {
    children.push_back(Person(i));
  }

  for(int i=0;i<Person::allPeople.size();i  ) {
    std::cout << Person::allPeople[i]->age;
  }

  return 0;
}

Right now, this code has 10 instances of the same object stored inside Person::allPeople. I think that it has to do something with how every time it loops around, the object goes out of scope. One of my solutions would be to make copies of the object and add pointers to those, except in my actual code, the objects' values would be changing frequently. If anyone knows what the best solution is please let me know, sorry if this is a bit of a messy question I can clarify if needed.

CodePudding user response:

 children.push_back(Person(i));

This is what happens here:

  1. Person(i) creates a temporary object. Person's constructor saves a pointer to this object in its private allPeople vector.

  2. The temporary object gets push_backed into the children vector. This copies/moves this object into the vector. The vector holds a copy of the original object that was added to it. The vector now has a completely different instance of the Person object, that was copy/move-constructed.

  3. After push_back() returns, the temporary Person object gets destroyed. allPeople is left with a dangling pointer to a destroyed object.

The reason you're seeing ten copies of the same pointer is because, it just so happens, every instance of the temporary object gets created in automatic scope at the same memory address. The shown code is completely blind to copy-constructed instances of Person, they get completely missed.

The rules of automatically and dynamically-scoped objects in C are complicated, and everything must be handled correctly. At the very least:

  1. Person() must implement a destructor to remove its this pointer from the allPeople vector.

  2. Person must implement, at the very least, a copy constructor that also stores the this pointer of the copy-constructed object in allPeople.

P.S. And let's not forget that every time std::vector reallocates its contents, this creates another batch of copy/move constructed objects, with the old objects getting destroyed.

  •  Tags:  
  • c
  • Related