I have checked Stack Overflow for a sample of these class vectors and none of the answers point out common uses of vectors in a class . My code works but I have a few questions on it .
I have a struck of objects that is stored in a class member vector
struct Station
{
std::string StationName;
int StationId;
int PlayerId;
std::vector<float> position;
};
Here is the class that declaration with the Vectors
class playerData
{
public:
std::vector <playerDataDetails> PlayerList;
std::vector<Station> Stations;
void addNewPlayer(std::string Name , std::string faction , int Id );
void PrintPlayer();
void AddStations(int PlayerNumber, std::string name);
};
When running the member function this is how Im accessing the Vector
void playerData::AddStations(int PlayerNumber, std::string name)
{
// p[i].
Station s ;
s.StationName = name;
s.StationId = 1;
s.PlayerId = PlayerNumber;
s.position = { 2.1f, 1.1f , 1.1f};
// s.position = { { 2.1f }, { 2.3f }, { 2.3f } };
this->Stations.push_back(s);
}
My question is this .
this->Stations.push_back(s);
- Is this the correct way to add station to the stations vector ?
- Is this copy or move Semantics ?
- Is there another way of doing this with pointers and references ?
- And is this the most efficient way of working with Vectors in a class ?
CodePudding user response:
Is this the correct way to add station to the stations vector ?
It's a perfectly fine approach, just a little inefficient.
Is this copy or move Semantics ?
Copy semantics (this->Stations.push_back(s);
invokes the version of push_back
taking a const
reference and copies it into the vector
).
Minimalist changes could avoid unnecessary copies by changing s.StationName = name;
to s.StationName = std::move(name);
and this->Stations.push_back(s);
to this->Stations.push_back(std::move(s));
, which is enough to replace all copies with moves (though additional changes could reduce the number of moves and potentially eliminate some temporaries).
Is there another way of doing this with pointers and references ?
Yes. Pointers don't help, but more careful use of move semantics and/or emplace*
semantics (to avoid temporaries entirely) could improve things (see below).
And is this the most efficient way of working with Vectors in a class ?
No. This could be done far more efficiently by avoiding some unnecessary copies and/or moves.
Without changing Station
, you could replace the entire body of AddStations
with either:
this->Stations.push_back({std::move(name), 1, PlayerNumber, {2.1f, 1.1f , 1.1f}});
or:
this->Stations.emplace_back(Station{std::move(name), 1, PlayerNumber, {2.1f, 1.1f , 1.1f}});
adding std::move()
around name
to avoid a copy in favor of a move, and avoiding a copy of Station
(it probably still needs to move-construct it into the vector though).
If you defined an explicit constructor for Station
, e.g. Station(std::string sn, int sid, int pid, std::vector<float> pos) : StationName{std::move(sn)}, StationId(sid), PlayerId(pid), position(std::move(pos)) {}
, you could also use:
this->Stations.emplace_back(std::move(name), 1, PlayerNumber, std::vector<float>{2.1f, 1.1f , 1.1f});
which would definitely avoid a move of a Station
object itself (though it still has to move the name
and the temporary vector
in the process of constructing it directly into the Stations
).
The various forms of weirdness in why each form of push_back
or emplace_back
works, or doesn't, with varying levels of explicitness is explained on this question.