Reputation: 83
I have the following code:
#include <map>
class vehicle {
private:
int id = 0;
std::map<std::pair<int, char>, int> seats{};
public:
void displaySeats();
};
class Bus : public vehicle {
private:
std::string type = "Bus";
public:
std::map<std::pair<int, char>, int> seats{ {{1,'A'},0 }, {{1,'B'},0 }, {{ 1,'C' }, 0}, {{ 1,'D' }, 0 }, {{ 1,'E' }, 0 },
{{2,'A'},0 }, {{2,'B'},0 }, {{ 2,'C' }, 0}, {{ 2,'D' }, 0 }, {{ 2,'E' }, 0 },
{{3,'A'},0 }, {{3,'B'},0 }, {{ 3,'C' }, 0}, {{ 3,'D' }, 0 }, {{ 3,'E' }, 0 },
{{4,'A'},0 }, {{4,'B'},0 }, {{ 4,'C' }, 0}, {{ 4,'D' }, 0 }, {{ 4,'E' }, 0 },
{{5,'A'},0 }, {{5,'B'},0 }, {{ 5,'C' }, 0}, {{ 5,'D' }, 0 }, {{ 5,'E' }, 0 }};
};
class MiniVan : public vehicle {
private:
std::string type = "MiniVan";
public:
// Seats map. <int, char> represents seats id(1A 1B 1C) the <int> will be either 0 or 1, representing if the seat is taken(1) or free(0).
std::map<std::pair<int, char>, int> seats{ {{1,'A'},0 }, {{1,'B'},0 }, {{ 1,'C' }, 0},
{{2,'A'},0 }, {{2,'B'},0 }, {{ 2,'C' }, 0},
{{3,'A'},0 }, {{3,'B'},0 }, {{ 3,'C' }, 0},
{{4,'A'},0 }, {{4,'B'},0 }, {{ 4,'C' }, 0} };
};
void vehicle::displaySeats()
{
std::pair<int, char> seat{ 1, 'E'};
int columns = 5?this->seats.count(seat)>0:3;
int displayRow = 0;
for (const auto& p : this->seats) {
if (displayRow == columns) {
std::cout << std::endl;
displayRow = 0;
}
displayRow++;
std::cout << p.first.first << p.first.second << "\t ";
}
};
In main() i have:
MiniVan testMiniVan;
testMiniVan.displaySeats();
It displays the empty seats map attribute from the base class. I am new to c++, but in other languages, it takes the derived class attribute. How can I solve this problem? Will I have to create displaySeats for each child class ? If yes, then why do I need base class in the first place?
Upvotes: 0
Views: 449
Reputation: 1260
This is something I've done fairly often as well, the issue is how things are constructed and which functions have access to which variables. Maybe you could do something like:
class Vehicle {
private:
int id = 0;
std::map<std::pair<int, char>, int> seats{};
public:
// Add a constructor that takes in the `seats` map
Vehicle(std::map<std::pair<int, char>, int> s) : seats(std::move(s)) {}
void displaySeats();
};
and then for each child class:
class MiniVan : public Vehicle {
private:
std::string type = "MiniVan";
public:
// call the parent constructor passing in the seat map
MiniVan() : Vehicle({{1,'A'},0 }, ...}) {}
};
Another approach would be to make a virtual function on the base class like:
class Vehicle {
...
protected:
...
const std::map<std::pair<int, char>, int>& get_seats() const = 0;
};
that the displaySeats
function would call instead of directly loading this->seats
. Each child class would need to define get_seats()
, but that would be pretty easy (pretty much just return seats;
). Hopefully that makes sense, let me know if not!
Upvotes: 2