Inheritance and lists - c++

I need to manage ants and colonies for a little game (for experiments in fact).
I have an Element class, which define all the entities in the game (ants, colonies, food, and other stuff…)
All other classes derive from this one.
My problem :
I have a class to manage all the entities. The player is able to select what he want. The selected entity is stored : Element* selection; If the selected intity is an Ant, the player can move it. But, because the selection variable is an Element pointer, I can't call the move() method which is in the Ant class, obviously.
What I consider to test :
If I implement a Element method called isMovable() which return true or false and maybe if the selection is movable, I will cast it to an Ant ? I don't know what is the right solution.
My move method:
void Manager::movementEvent(sf::Vector2i mPosition)
{
sf::Vector2f mousePosition = sf::Vector2f((float)mPosition.x, (float)mPosition.y);
if(this->selection) {
// I need to move the selected Ant
}
}
Thank you for your help !!
EDIT
Here my actual design :
class Element {
private:
sf::Vector2f position;
int width, height;
public:
Element();
Element(sf::Vector2f position, int width, int height);
Element(const Element & element);
virtual ~Element();
};
class Colony: public Element {
private:
int capacity;
Queen *queen;
public:
Colony();
Colony(sf::Vector2f position, int width, int height, int capacity, Queen &queen);
Colony(Colony const & colony);
virtual ~Colony();
Colony& operator=(Colony const& colony);
};
class Ant: public Element
{
private:
sf::Vector2f destination;
int number, age, speed;
public:
Ant();
Ant(sf::Vector2f position, int number, int age, int width, int height, int speed);
Ant(const Ant & ant);
virtual ~Ant();
Ant& operator=(Ant const& ant);
};
class Manager {
private:
std::vector<Element*> ants;
std::vector<Element*> colonies;
Element* selection;
std::vector<Ant*> movement;
public:
Manager();
virtual ~Manager();
std::vector<Element*> getAnts();
std::vector<Element*> getColonies();
void addAnt(Ant* ant);
void addColony(Colony* colony);
void removeAnt(Ant* ant);
void removeColony(Colony* colony);
void draw(sf::RenderWindow * window);
void drawElement(sf::RenderWindow * window, std::vector<Element*> vector);
void selectionEvent(sf::Vector2i mousePosition);
bool checkSelection(sf::Vector2f mousePosition, std::vector<Element*> vector);
void movementEvent(sf::Vector2i mousePosition);
};

I would prefer to avoid the design in general, as it strikes me as a forced fit at best.
A base class should define behaviors that are common between a number of derived classes and provide a common interface to that common behavior. In this case, however, it seems likely to me that your derived classes have practically no common behavior, so you'll have little or nothing in the way of a useful common interface between them.
That being the case, you're likely to lose a great deal more than you gain by forcing them all to derive from a (basically meaningless) "entity" class. In fact, I'd suggest that almost any time you find yourself thinking in terms of a class name as general as "object" or "entity" that doesn't suggest a meaningful set of behaviors, chances are pretty good that you're trying to shove things together that don't really belong together.
All that said, if you really insist on doing this anyway, I'd adhere to the basic maxim that it's better to tell than ask. As such, I'd define a try_to_move (or possibly just name it move) in the base class, but provide a default definition that just fails. Then override that in the Ant class to actually move.
class Entity {
// ...
virtual bool move_to(Location new_location) {
return false;
}
};
class Ant : public Entity {
// ...
virtual bool move_to(Location new_location) {
my_location = new_location;
return true;
}
};
This way you can tell anything derived from Entity to move -- but if you tell a Food object to move, it'll just fail. This simplifies the calling code considerably. Instead of a pattern like:
if (object->can_move()) {
if (object->move_to(new_location))
// succeeded
else
// failed
}
We get code like:
if (object->move_to(new_location))
// succeeded
else
// failed
At least in a typical case, we're likely to end up dealing with the possibility of failure even when we've told an ant to move, so adding the element of asking the object whether it can move before asking it to do so really gains us nothing anyway.
Depending on the situation, you might want to change the code a little, so different reasons for failing to move return different error codes, so when/if it fails, you can sort out why. Alternatively, you might prefer to write the code so that it either succeeds at moving, or else throws. Under these circumstances (where you rather expect it to fail at least part of the time) that's probably not the best alternative, but it may still be worth considering.
I'll reiterate, however, that I think a better design is probably to just keep Ants and Food separate, so it's easy to deal with Food as food, and Ants as ants, and not have to sort out at run-time whether something is Food or an Ant to know how you can interact with it.

This really smells like you are solving the wrong problem. You will be able to get it to work using flags like isMovable and casting, but your code is likely to turn into a mess and give you a headache.
Perhaps your problem is actually
"I have a class to manage all the entities"
If they are in no way related, they probably should not express an Is-A relationship to Entity. It might be cleaner if you have different containers for each type. How you tie up the actions the user wants with "entities" will be another matter.

You can add a virtual method move() on your base class, than implement it only for the Ant class, so when it's checked the Element is movable, it should move:
class Element
{
public:
Element(bool movable) : m_movable(movable) {}
virtual void move() {};
bool isMovable() const { return m_movable; }
private:
bool m_movable;
};
class Ant : public Element
{
public:
Ant() : Element(true) {}
void move() { /* move */ }
};
class Food : public Element
{
public:
Food() : Element(false) {}
};
In this way every derived class has a move() method, indeed, but it's the inherited from the base class (so it's left blank).
EDIT
Occam's razor tells us that in this case you also don't have the need of the bool m_movable flag, so the snippet simplifies in:
class Element
{
public:
Element() {}
virtual void move() {};
};
class Ant : public Element
{
public:
Ant() {}
void move() { /* move */ }
};
class Food : public Element
{
public:
Food() {}
};

Related

Template class and nested class C++

I have a problem with typename SnakeGame. I would like to know how to make SnakeGame to global type in class KeyboardEvents. Now a nested class like DirectionKeyboard don't know what the type SnakeGame is, since it only sees see KeyboardEvents<SnakeGame> type. I don't know how to change it :P
Here's the error:
no know conversion for argument 1 from 'KeyboardEvents SnakeGame>&' to 'SnakeGame&'
I would really appreciate help .
keyboardEvents.hpp
#include<SFML/Graphics.hpp>
template <typename SnakeGame>
class KeyboardEvents {
public:
virtual ~KeyboardEvents() = default;
protected:
class DirectionKeyboardEvent{
public:
virtual ~DirectionKeyboardEvent() = default;
virtual void direction(SnakeGame&) = 0; // error no know conversion
};
class GoRight : public DirectionKeyboardEvent {
public:
void direction(SnakeGame& snakeObj) {
snakeObj.snake[0].xCoor+=1;
}
};
class GoRight : public DirectionKeyboardEvent {
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor += 1;
}
};
class GoLeft : public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor-=1;
}
};
class GoUp:public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor-=1;
}
};
class GoDown : public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor+=1;
}
};
std::map<sf::Keyboard::Key, std::shared_ptr<DirectionKeyboardEvent>> mapOfDirects;
void initializeDirectionMap() {
mapOfDirects[sf::Keyboard::Right] = std::shared_ptr< DirectionKeyboardEvent >(new GoRight);
mapOfDirects[sf::Keyboard::Left] = std::shared_ptr<DirectionKeyboardEvent>(new GoLeft);
mapOfDirects[sf::Keyboard::Up] = std::shared_ptr<DirectionKeyboardEvent>(new GoUp);
mapOfDirects[sf::Keyboard::Down] = std::shared_ptr<DirectionKeyboardEvent>(new GoDown);
}
void chooseMethodFromKeyboardArrows(sf::Keyboard::Key codeFromKeyboard) {
auto iterator = mapOfDirects.find(codeFromKeyboard);
if(iterator!=mapOfDirects.end()){
iterator->second->direction(*this);//left , right,up , down, pause
mainDirection=codeFromKeyboard;
} else {
mapOfDirects[mainDirection]->direction(*this);
}
}
};
Here's the class where I use KeyboardEvents ~ snakeGame.hpp
#include"keyboardEvents.hpp"
class SnakeGame:public Screen, public KeyboardEvents<SnakeGame> {
public:
SnakeGame(int size=16, int width=15, int height=15, int timeDelay=60000)
: Screen(size, width, height), KeyboardEvents<SnakeGame>(), timeDelay(timeDelay) {}
};
In your try to call the DirectionKeyboardEvent::direction inside the KeyboardEvents class.
Even if you put a template parameter that happens to be the child class, there is no means to compiler can know in advance that KeyboardEvents<SnakeGame> will absolutely be extended by the class SnakeGame.
I mean, one could write this code:
KeyboardEvents<SnakeGame> keyboardEvents;
keyboardEvents.chooseMethodFromKeyboardArrows(/* some key */);
In that case, keyboardEvents is not related that much to SnakeGame. In fact there is no SnakeGame instance created at all! The compiler is right, the function chooseMethodFromKeyboardArrows that call direction is wrong to assume that a KeyboardEvents<SnakeGame> is a SnakeGame.
Inheritance work the other way around: a SnakeGame is indeed a KeyboardEvents<SnakeGame>. The other way is false.
I could show you how "to make it work", but a warning is needed here: you are overusing inheritance, and you used it the wrong way in the case of KeyboardEvent. You really should try to rearrange things around, or you'll end up in a real mess.
The solution "make it work"
Since you are using CRTP, you can tell the compiler that KeyboardEvents<SnakeGame> is indeed, in absolutely ALL cases, being extended by SnakeGame. If that's really the case, you can just static_cast your base class to the child class:
if(iterator!=mapOfDirects.end()){
// Notice the presence of the cast here
iterator->second->direction(static_cast<SnakeGame&>(*this));
mainDirection=codeFromKeyboard;
}
The slightly better solution
You can as well using an existing instance of your snake class as parameter.
void chooseMethodFromKeyboardArrows(sf::Keyboard::Key codeFromKeyboard, SakeGame& game){
auto iterator = mapOfDirects.find(codeFromKeyboard);
if(iterator!=mapOfDirects.end()){
iterator->second->direction(game);
mainDirection=codeFromKeyboard;
} else {
mapOfDirects[mainDirection]->direction(game);
}
}
However, the best idea is to not make SnakeGame extending KeyboardEvent, but to contain it in the class instead:
struct SnakeGame : Screen {
KeyboardEvent<SnakeGame> event;
void callEvents() {
event.chooseMethodFromKeyboardArrows(/* some key */, *this);
}
};
Here's an homework for you:
Try to make the class KeyboardEvent not a template. I'm sure you can find a way to pass around your class without the use of themplates, while still accessing directly to your class SnakeGame, without casts or interfaces.
Your design seems a bit overcomplicated. I think the reason this is so is perhaps you were designing it as you went along. Sometimes it helps to sit down and think about these things first, draw boxes and lines on a whiteboard if you have to.
In any case, this isn't a direct answer to your question, it's a suggestion for an alternative based on what I'm guessing you are trying to do.
It seems to me that you're trying to implement some generic keyboard input handler and tie it in to your game. It's possible that I'm entirely wrong about this, but if not, consider something like this instead. First, a generic interface for things that receive keyboard events. It need not be a template, this isn't really a good use-case for templates:
class KeyboardEventHandler {
public:
enum Direction { Left, Right, Up, Down };
virtual ~KeyboardEventHandler () { }
virtual void onDirectionKey (Direction d) = 0;
};
Now your SnakeGame, which handles keyboard events, can inherit that and implement its own SnakeGame-specific logic:
class SnakeGame : public KeyboardEventHandler {
public:
void onDirectionKey (Direction d) {
switch (d) {
case Up: ...
case Down: ...
case Left: ...
case Right: ...
}
}
};
And then whatever bit of code you have that is actually processing keyboard events and driving all of this can just work with a KeyboardEventHandler *, which could be a SnakeGame, or could be anything else you decide to use it for in the future.
That's just one possibility for organization. For example, you could structure it like this instead, breaking out the KeyboardEvent, which could simplify future additions:
class KeyboardEvent {
public:
enum Direction { Left, Right, Up, Down };
Direction getDirection () { ... } // or whatever
};
class KeyboardEventHandler {
public:
virtual ~KeyboardEventHandler () { }
virtual void onEvent (KeyboardEvent &event) = 0;
};
With SnakeGame as:
class SnakeGame : public KeyboardEventHandler {
public:
void onEvent (KeyboardEvent &event) {
...
}
};
You could name that stuff something else besides Direction / onDirectionKey if you want, I picked that from your example but just make it something semantically appropriate that is also convenient (e.g. if you plan on expanding it to include more than just the arrows). But whatever, that's beside the point.
There are also 10 zillion other ways to skin this cat but the important take-home point is: If you're trying to make some generic interface for something, you really can't make it rely on the specific details of what inherits it, otherwise you're defeating the purpose of making it general to begin with. In that case, either it's not a good case for generic bases / inheritance, or you've just botched the design and need to sit back and rethink.
Remember: Your goal isn't to add as many classes and stuff as possible to your code; you're not going for like, an inheritance high score. Your goal is to keep your code clean, readable, maintainable, correct, possibly reusable, and to make your work easier on yourself. These are tools, don't just use them because you have them, instead use them when you need them to make your life easier.
However, all that said, this is still overkill for your specific application, although it is an interesting exercise. To be honest, in your specific case, I'd just chuck all the inheritance and such altogether and do something like:
class SnakeGame {
public:
void handleKeyPress (char c) {
// ... do the right thing here
}
}
And be done with it.

Prevent breaking encapsulation

I have this class:
class Phone {
private:
string producer, color;
int weight, dimension;
public:
Phone(string &producer, string &color, int &weight, int &dimension):
producer(producer), color(color), weight(weight), dimension(dimension) {};
Phone():
producer(""), color(""), weight(0), dimension(0) {};
virtual ~Phone() {};
string getProducer(void) const;
string getColor(void) const;
int getWeight(void) const;
int getDimension(void) const;
virtual void displayInfo(void) const;
};
The problem is here caused by the fact that I expose the internal implementation of the object via getters.
But how can I prevent this?
Because usually in my code, I need to know some private data from my object (for comparision is one example), and that's why I use getters.
So then I rewrite the class to something like this:
class Phone {
private:
string producer, color;
int weight, dimension;
public:
Phone(string &producer, string &color, int &weight, int &dimension):
producer(producer), color(color), weight(weight), dimension(dimension) {};
Phone():
producer(""), color(""), weight(0), dimension(0) {};
virtual ~Phone() {};
bool isTheProducer(string& producer) const { return this->producer == producer };
bool hasWeight(int& weight) const { return this->weight == weight };
bool hasDimension(int& dimension) const { return this->dimension == dimension };
virtual void displayInfo(void) const;
};
Is this a better design (by the fact that I don't get the actual private value)?
As you might have seen from the other answers and comments, the answer is: It depends.
In fact, it depends mainly on the usecases where your class is used. Let's stick first to the example given in the question, the comparison of objects. Since it is not clearly visible from the question if we want to compare two phone objects or just a specific data member I will discuss both situations here.
Comparing a data member to out-of-class data
Let's take this usecase where we search for all phones with a weight bigger than x(just pseudocode):
for (Phone& p in phoneList) {
if (p.getWeight() > x) {
cout << "Found";
}
}
Then the first class example is perfectly fine, since this is not an intrinsic feature of the phone, and thus the phone class is not responsible for handling it. In addition, the result does not expose more than absolutely required for the task.
Comparing two phone objects
In this case both code examples are equally good (or in this case equally bad). In both cases the user has to know a lot of details about how phones are represented to compare all necessary members. If in a later revision a new member is added to the class, every code segment that compares two phones has to be adapted. To overcome this, one can add a function to the class that does exactly the comparison.
class Phone {
private:
string producer, color;
int weight, dimension;
public:
bool IsEqualTo(const Phone& other)
{
return (producer == other.producer && color == other.color &&....);
}
Non comparitive usecase
But let's go to a more advanced example. Let's assume the following task: A user enters the pin to a phone and if it is the correct one, the phone should unlock. Let's assume a very naive approach:
class Phone
{
private:
int pin;
bool unlocked;
public:
int getPin() { return pin; }
void unlock() { unlocked = true; }
};
and the corresponding call
if (phone.getPin() == enteredPin)
phone.unlock();
In this case we have a totally different situation. Here we need to consider the "tell, don't ask" rule, which basically says that it is a bad design to query the state of an object first, make a decision and then tell the object what to do. Instead we should only tell the object what we want, and let it do the work for us. In this usecase this is obvious, since unlocking the phone only when the pin is correct is a responsibility of the phone, not of the user that uses the phone class. But in more complex scenarious many programmers will do exactly what I described here.
Back to the problem: A good solution here would be for example
class Phone
{
private:
int pin;
bool unlocked;
public:
void CheckPin(int enteredPin) {
if (pin == enteredPin)
unlocked = true;
}
};
with the code
phone.CheckPin(enteredPin);
Hope this helps, and thanks to #KonradRudolph for pointing to the "tell, don't ask rule". Feel free to help me to improve the answer per commenting on it :)
The first one, even with getter, is encapsulated. Consider the color() method, which returns a string. Even if you change the implementation of Phone such that you store the color as an enum rather than a string, your method can still return a string if you do some sort of conversion first. The important part is that you can change the implementation of color() and the underlying storage without users of the class needing to change.
Compare to a class that stores color as a publicly accessible string. If you later change the data member to an enum, you need to modify every location that uses the color. This is less of a property of encapsulation and more a property of separating interface from implementation.
Encapsulation allows controlling of attributes exclusively via methods within the class. Both examples are encapsulated.

Converting objects of base class to derived class

I asked a couple days ago some clarifications on inheritance, a concept I am still trying to understand. Here is the follow up question, since I am still facing problems.
In my project I have 2 types of objects, Hand and Face, both inheriting from the base class BodyPart. BodyPart is something like this:
class BodyPart
{
public:
typedef boost::shared_ptr<BodyPart> BodyPartPtr;
BodyPart();
virtual ~BodyPart();
private:
int commonMember1;
double commonMember2;
public:
int commonMethod1();
int CommonMethod2();
}
while Hand is something like this:
class Hand : public BodyPart
{
public:
Hand();
~Hand();
private:
int numFingers;
double otherVar;
public:
int getNumFingers();
void printInfo();
}
I also have a vector of BodyPart elements
std::vector<BodyPart::BodyPartPtr> cBodyParts;
composed of Hand or Head objects. In the previous question I was told that this approach makes sense, I just had to cast from the base class to the derived using boost static_pointer_cast
Now, the problem now is that for some of the objects in the vector I don't know whether they are Hand or Head, so at some point in my code I can have in cBodyParts some Hand elements, some Head elements as well as some BodyPart elements. After some further analysis I am able to correctly classify the latter as either Hand or Head and modify accordingly the elements in the vector, but I have no idea on how to make it. Shall I just delete the case class element and create a derived one with the same property? Shall I just avoid inheritance in case like this?
Thanks in advance for the help
EDIT: I have augmented the examples to make them clearer.
Relaying on casts is usually a sign of a bad design. Casts have their place, but this does not look to be it.
You need to ask yourself what do you want to do with the objects stored in cBodyParts. For sure, you will be doing different things with a Hand or with a Head, but you can probably abstract them somehow: this is what virtual functions do. So, in addition to what you have already written for your classes, you would just need an additional virtual function in them:
class BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() = 0; // Pure virtual: each body part must say how to process itself
virtual void CalibrateJoints() {} // Override it only if the body part includes joints
}
class Head : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Head
}
// Since a Head has no joints, we don't override the CalibrateJoints() method
}
class Hand : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Hand
}
virtual void CalibrateJoints() {
// Code to calibrate the knuckles in the hand
}
}
And then you no longer need any casts. For instance:
for (BodyPart::BodyPartPtr part : cBodyParts) {
part->InitialisePart();
part->CalibrateJoints(); // This will do nothing for Heads
}
As you can see, no casts at all and everything will work fine. This scheme is extensible; if you later decide that you need additional classes inheriting from BodyPart, just write them and your old code will work correctly:
class Torso : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Torso
}
// The Torso has no joints, so no override here for CalibrateJoints()
// Add everything else the class needs
}
class Leg : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Leg
}
virtual void CalibrateJoints() {
// Code to calibrate the knee
}
// Add everything else the class needs
}
Now you don't need to change the code you wrote previously: the for loop above will work correctly with and Torso or Leg it finds with no need for an update.
The hip bone's connected to the thigh bone...
I take it you have some composite of all the body parts, maybe a Body class.
What do you want the body to do?
Render itself
Serialise
Ouput its volume, or bounding box, or some other metric
Re-orient itself in response to input
Respond to an inverse-kinematic physical model
The list could probably go on. If you know exactly what you want the Body to do you can put that function in the BodyPart base class, and have Body iterate over the composite hierarchical structure of all the connected body parts, calling render, for example.
An alternative is to use a Visitor, which is effectively a way of dynamically adding methods to a static inheritance hierarchy.
As Kerrek SB pointed out this is not feasible at all, but for the sake of answering the actual question, dynamic_cast is what you are looking for.
Use virtual functions, they will simplify a lot your problem.
Else, you can add some methods to distinguish between different types. However, do it only if you cannot do it another way, ie if you cannot do it via virtual functions.
Example 1:
// in BodyPart; to be reimplemented in derived classes
virtual bool isHand() const { return false; }
virtual bool isHead() const { return false; }
// in Hand (similar to what will be in Head)
bool isHand() const { return true; }
// How to use:
BodyPart::pointer ptr = humanBodyVector[42]; // one item from the array
if(ptr->isHand())
processHand(/*cast to hand*/)
else if(ptr->isHead())
// ...
Example 2: let the derived classes handle the cast
// in BodyPart; to be reimplemented in derived classes
virtual Hand* toHand() const { return 0; }
virtual Head* toHead() const { return 0; }
// in Hand (similar to what will be in Head)
Hand* toHand() const { return this; }

Parent - Child Relation in C++

Consider the below C++ code
class B;
class A{
private:
B* mB;
};
class B{
private:
doSomethingImportant();
};
We have a Object A that contains (has a) Object B. The parent being A and child being B. Now if I want A to make B do doSomethingImportant() , I see that adding A as a friend of B is the only way to do it.
friend class A inside class B. This would enable A's functions to access B's private function.
I find this approach a little weird since creates a loophole in the Data_Hiding concept. Is there a better way to establish a parent-child relationship between the object ? or is this the best way ?
Adding my actual motivation for this question
class elevator{
private:
//The Lift box the elevator controls
liftboxControlUnit & mLiftBoxCtrlUnit;
//constructor
elevator(int Level=1, int NoOfBanks =1 );
//Destructor
~elevator();
//Triggers the search to move to the next floor if required
void moveLiftToNext();
public:
//Adds request to the queue
void addRequest(int FloorNumber){
//Add the request to the queue. The single button outside the elevator door
mLiftBoxCtrlUnit.addRequest(FloorNumber);
}
//For Emergency. Should be accessible to everyone !
void setEmergency();
void unsetEmergency();
};
typedef enum Direction{
UP,
DOWN
}direction;
class liftboxControlUnit{
private:
//The request for various floors
set<int> mRequestQueue;
//The various banks for the whole system
vector<Bank> mBanks;
//The total number of levels. Remains the same for one building
const int mTotalLevel;
//Instruction to move the box to certain level
void processRequest(){
//Do the logic to move the box.
}
//can passed to the elevator
void addRequest(int x){
mRequestQueue.insert(x);
}
//Can be set by elevator class
void setEmergency(){
//Do the required
//Set Emergency on all Banks
}
void unsetEmergency(){
//UnsetEmegency on all banks
}
void emergencyListener(){
//Listen to all the banks if emergency has been set
}
void BankFreeListener(){
//Listen to the banks if any is free
//If so then
processRequest();
}
public:
//Constructor
liftboxControlUnit(int TotalLevels, int NoOfBanks): mTotalLevel(TotalLevels){
for(int i=0 ; i lessthan NoOfBanks; ++ i)
mBanks.push_back(Bank(0,UP));
}
friend class elevator;
};
class Bank{
private:
//The dailpad inside the bank
dailpad & mpad;
//Current Location
int mPresentLevel;
//Current direction of movement
direction mDirection;
//Currently moving
bool mEngaged;
//Manipulate the bank
void move(int NoOfMoves){
setEngaged();
//Move the elevator
unsetEngaged();
}
//getters
int getPresentLevel() const;
int getDirection() const;
//setters
void setPresentLevel(int);
void setDirection(direction);
//Manipulate the engaged flag
bool isEngaged() const;
bool setEngaged();
bool unsetEngaged();
//For emergency
void reset();
//Dailpad Listener
void dailpadListener(){
}
public:
Bank(int StartingLevel, direction Direction): mPresentLevel(StartingLevel),
mDirection(Direction),
mEngaged(false),
mpad()
{
}
//For emergency . Should be available for all.
void SetEmergency();
void UnsetEmergency();
bool isEmergency();
friend class liftboxControlUnit;
};
class dailpad{
private:
//Some DS to represent the state . probably a 2D Array.
void renderDisplay();
public:
//Constructor
dailpad();
void getCommand(int x){
//Depending on the value we can do the following
//Make necessary changes to the display
renderDisplay();
}
friend class Bank;
};
IMO, for this task you should probably nest the "lift box" class inside of the controller class:
class lift_controller {
class lift_box {
open_doors();
close_doors();
move_to_floor();
};
std::vector<lift_box> bank;
};
To the outside world, there need be no evidence that lift_box exists at all. It communicates exclusively with the lift_controller, and all outside communication with a lift_box goes through the lift_controller.
In this case (only lift_controller has access to lift_box at all), it seems clear (at least to me) that any operations the lift_controller may need to invoke on a lift_box should just be made public functions of lift_box. To enforce nobody else having access to lift_box, ensure that the definition of lift_box is in the private: section of lift_controller.
Edit: I should add that quite a bit of the design you've edited into your question above makes little or no sense to me. Just for example, you have things like direction and present level for the bank. Unless I'm completely misunderstanding what you mean by a bank, this seems like a clear error to me -- the bank isn't at a particular level or moving in a particular direction. Rather, each individual elevator in the bank is at some level and (potentially) moving in some direction.
You seem to want class A to only be able to access one private function in B, B::doSomethingImportant() and no other private functions.
This usually means that B::doSomethingImportant() should really be public. Like this, A will not be able to access other private data members of B.
Further, if you do not want other classes to access B::doSomethingImportant(), they should not hold a pointer to B but instead, a hold a pointer to an interface (abstract super class) of B that does not expose B::doSomethingImportant().
Or perhaps other classes only read data from B. In that case they can hold B const * which will not allow them to call B::doSomethingImportant() unless they do a const_cast.

Best way to alias methods of member object? "Passthrough methods"

Consider the following code:
class Rectangle
{
public:
// Constructors
Rectangle(){ init(0,0); }
Rectangle(int h, int w){ init(h,w); }
// Methods
void init(int h, int w)
{
_h = h;
_w = w;
}
// Getters / Setters
double get_h(void){ return _h; }
double get_w(void){ return _w; }
void set_h(double h){ _h = h; }
void set_w(double w){ _w = w; }
std::string get_name(void){ return _name; }
void set_name(std::string name){ _name = name; }
private:
// Private Members
int _h, _w;
std::string _name;
};
class House
{
public:
// <BEGIN PASSTHROUGHS>
std::string get_b_name(void){ return _base.get_name() };
std::string get_r_name(void){ return _roof.get_name() };
void set_b_name(std::string name){ _base.set_name(name); }
void set_r_name(std::string name){ _roof.set_name(name); }
// </END PASSTHROUGHS>
private:
// Private Members
Rectangle _base;
Triangle _roof;
};
This code works fine.
My question deals with the "passthrough" functions in the House class, enclosed by the PASSTHROUGHS tags. Is this the best way to do this? The arguments and return types will always match and there is no "intelligence" in these passthrough functions other than to make things cleaner and more straightforward.
My instinct would be something like one of the following:
get_b_name = _base.get_name;
// OR
std::string get_b_name(void) = _base.get_name;
... but neither seem to work unfortunately and it was only wishful thinking in the first place. If there are no easier options, telling me that is fine too. Thanks!
The problem, I think, is conceptual. Your design is quite un-object oriented in that the house does not represent an entity, but rather provides a bit of glue around the components. From that standpoint, it would make more sense to provide accessors to the elements, rather than pass-through functions:
class House {
Rectangle _base;
Triangle _roof;
public:
const Rectangle& base() const {
return _base;
}
const Triangle& roof() const {
return _roof;
}
};
I imagine that this is just a toy example, but the same reasoning applies: a class should represent an entity on which a set of operations are preformed, in some cases those operations might be implemented in terms of internal subobjects, but they are still operations on the type, and how they are gathered is an implementation detail.
Consider:
class House {
Thermostat t;
public:
int temperature() const {
return t.temperature();
}
};
From the user point of view the house has a temperature that can be read, and in this particular implementation, it is read from a thermostat that is a member. But that is an implementation detail. You might want to later install more thermostats in the house and substitute the single reading by an average of the readings, but that will not change the fact that the entity House (in this model) has a temperature.
That is, you should not be thinking in implementing pass-through functions, but rather on implementing features of the type. If the implementation happens to be a single forwarding to an internal method, that is fine.
But if the type contains internal members and it makes sense to access properties of the members, consider that it might be that you actual type should just provide access to its internal members. Consider that you want to move a piano inside the house, then you might just provide access to the door member and let the user check:
class House {
Door d;
public:
Door const & door() const {
return d;
}
};
bool can_enter_piano( House const & h, Piano const & p ) {
return h.door().width() > p.size();
}
There is no need to provide House::get_door_width(), and House::get_door_color() so that you can describe the entrance to a friend, and House::get_door_handle() so that they can know when they arrive...
That's possibly because your design is contradictory. Why on earth would you make a public member variable, then write a function that just forwards to one of that variable's functions? As a user of your class, I'd just call the function on the public variable myself. You're just confusing me by providing two ways to do the same thing. Or write getters and setters for a Rectangle class? That thing is just a bunch of variables, and doesn't need any getters and setters. You're not exactly going to inherit from it, and you can't really change the internal logic and maintain the same semantics, so it's very meaningless to not just make the variables public.
The Rectangle class needs a very healthy dose of YAGNI, and the House class just needs to look at itself again. The fact that there's no intelligence in the "passthrough" methods should be a huge alarm bell telling you that they are quite probably redundant and not helpful- especially since you can't change the public variables without breaking your interface anyway, it's not like the getters and setters are decreasing coupling or anything like that.
Methods should perform logic, or in the very least case, exist where logic might have to be done.