askman
askman

Reputation: 516

Is there a way to make a vector of objects on construction via which members can be altered?

I'm trying to find a way to add objects to a vector upon construction which allows for the members of the objects to be altered.

I'm familiar with using a static member vector, but these seem to lock the instance values at the initialized state, i.e:

class This {
    public:
        static std::vector<This> group;
        std::string name;
        This(std::string n) : name{n} {
            group.push_back(*this);
        }
};
std::vector<This> This::group;

This one("1");      // one.name == "1"
This two("2");      // two.name == "2"
This three("3");    // three.name == "3"

This::group[0].name // == "1"

one.name = "5";     // name successfully changed to "5"

This::group[0].name // == "1" however one.name == "5"

Upvotes: 1

Views: 77

Answers (2)

Corristo
Corristo

Reputation: 5510

If you store pointers to the elements in your vector instead of copies then it'll work

class This {
public:
  static std::vector<This*> group;
  std::string name;
  
  explicit This(std::string n) 
    : name{std::move(n)} 
  {
    group.push_back(this);
  }
  This(This const&) = delete;
  This(This&&) = delete;
  This& operator=(This const&) = delete;
  This& operator=(This&&) = delete;
  ~This() 
  { 
    group.erase(std::remove(group.begin(), group.end(), this),
                group.end());
  }
};

Note that this is not thread-safe, though, so you can't create new This objects in one thread while accessing or deleting This objects in another. There might also be issues with invalidation of the indices or iterators into the vector, so as @SergeyA suggested in their comment it is better avoided.

Upvotes: 4

Gwendal
Gwendal

Reputation: 107

when you call push_back(*this) a copy of your object is created. So if you want your vector to be linked with the objects you've created you need to store a vector of pointer to your object :

class This {
    public:
        static std::vector<This*> group;  //vector of pointer instead of objects
        std::string name;
        This(std::string n) : name{n} {
            group.push_back(this); //pointer instead of the pointed value
        }
};
std::vector<This> This::group;

This one("1");      // one.name == "1"
This two("2");      // two.name == "2"
This three("3");    // three.name == "3"

(*This::group[0]).name // == "1"

(*one).name = "5";     // name successfully changed to "5"

This::group[0].name    // the returned value should be "5"

Upvotes: 0

Related Questions