This is my base class where I have method PrintInfo which will be overriden in the child classes.
class Place
{
private:
std::string Name;
int Population;
std::string County;
public:
Place(std::string name,int population,std::string county)
{
Name = name;
Population = population;
County = county;
}
virtual void PrintInfo()
{
std::cout << Name << " is with population around " << Population << " and it is in " << County << " county.";
}
};
Below are other two child classes:
class Town : public Place
{
private:
std::string UniversityName;
public:
Town(std::string name, int population, std::string county,std::string universityName) :Place(name, population, county)
{
UniversityName = universityName;
};
void PrintInfo()
{
Place::PrintInfo();
std::cout << "This town has an university - " << UniversityName << std::endl;
}
};
class Village : public Place
{
private:
std::string SchoolName;
public:
Village(std::string name, int population, std::string county, std::string schoolName) : Place(name,population,county)
{
SchoolName = schoolName;
};
void PrintInfo()
{
Place::PrintInfo();
std::cout << "Also it is a village and it has a school - " << SchoolName << std::endl;
}
};
So in the main I have the following:
int main()
{
Town town (townName,townPopulation,townCounty, university);
Village village (villageName, villagePopulation, villageCounty, school);
vector<Place> places;
places.push_back(town);
places.push_back(village);
for (auto x : places)
{
x.PrintInfo();
}
}
I use vector of type Place because I want to store simultaneously the town object and the village object. When I call the PrintInfo method I want to retrieve the initial information from the base calss and after that to add the information from the child class. At all when I call mehod PrintInfo it shows me only the content in the base class Place. I want to have full access to the information when I call this method.
In your example you are slicing your objects, copying only the base class over to the objects stored in the vector.
std::vector
is for things where you have a variable number of objects at runtime. According to your question, you have a fixed number that is known at design time: One town and one village. I suggest to store it differently:
template <typename Tup, typename F, std::size_t... I>
void visitTuple(Tup const& tup, F&& f, std::index_sequence<I...>) {
(f(std::get<I>(tup)), ...);
}
template <typename Tup, typename F>
void visitTuple(Tup const& tup, F&& f) {
visitTuple(tup, std::move(f), std::make_index_sequence<std::tuple_size_v<Tup>>{});
}
std::tuple<Town, Village> places{Town{/*town arguments*/}, Village{/*...*/}};
visitTuple(places, [](auto const& place) {
place.PrintInfo();
});
This is strongly typed and should optimise nicely. You don't even need a common base class or polymorphism.
Note: This will only work if indeed the amount of places is fixed as you suggest in your OP. If it is, however, determined at runtime, instead use std::vector<std::unique_ptr<Place>> places;
.