0

This is similar to other questions I'm sure, I read through. I am trying to write a move class. I need a Player class and an Item class that inherits the move class, or vice versa. That is what I am having difficulty with. I can't wrap my head around, or get to work, a way that the base class is not "Move." I'm lost here...

class Player {

protected:
    int x;
    int y;
    int str;
    int speed;
    int level;
    int exp;

public:
    Player(int _str, int _speed, int _level, int _exp) { x=0;y=0;str=_str;speed=_speed;level=_level;exp=_exp; }
    int GetX() {return x;}
    int GetY() {return y;}
    int GetStr() {return str;}
    int GetSpeed() {return speed;}
    int GetLevel() {return level;}
    int GetExp() {return exp;}

};


class Move : public Player {
public:
    void TryMove(int n) { x += n; }
};


int main(int argc, char *argv[])
{
Player You(101, 5, 3, 43625);


//You.TryMove(5); how?


}

TryMove(5) fails. If I do it the other way, then they type is then Move (?) and that doesn't sound right at all...

Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
  • First, this seems more appropriate for http://programmers.stackexchange.com/. Second, it will be helpful to know the purpose of these classes before answering your questions. – R Sahu Jun 09 '14 at 03:35

2 Answers2

2

First of all, public inheritance means IS-A relationship. So Move IS-A Player does not make any sense. Your design is wrong.

About your error, this is just silly. You are creating a Player object You and calling method of Move on it. To use methods of class Move, you have to create object of Move(or any publicly derived class).

class Move : public Player {
  public:
   //either create a ctor that will pass params to parent ctor, or create an empty ctro in parent class
   Move(int _str, int _speed, int _level, int _exp):Player(_str,_speed,_level,_exp){} 
   void TryMove(int n) { x += n; }
};


int main(int argc, char *argv[]){

  Move You(101, 5, 3, 43625);
  You.TryMove(5); 
}

I would design it as following:

class Movable{
    public:
     virtual bool TryMove()=0;
};

class Player: public Movable {
 public:
  bool TryMove() override{
    //implementation code
  }

 //other members
};

 int main(){
  Movable*  player = new Player(101, 5, 3, 43625);
  player->TryMove();
  delete player;
}
Community
  • 1
  • 1
Rakib
  • 7,435
  • 7
  • 29
  • 45
  • Thanks. What I am trying to do is have the "player" define everything about the player, the "item" class is basically the same. Both the player and item class will have protected variables, x, y, width and height. The move class has all member functions to change x and y values. I am/ was planning on being able to declare "Player" as normal, same for "Item", and be able to move using functions from "Move". – Evan Carslake Jun 09 '14 at 03:47
  • @EvanCarslake Derive `Player` from `Move` then? – Appleshell Jun 09 '14 at 03:51
  • @Appleshell, that is what I was thinking, but it seemed odd calling all player properties through the move class. – Evan Carslake Jun 09 '14 at 03:57
  • @EvanCarslake You can modularise it if you want. Create a `Positionable` with x and y, `Movable` to derive from Positionable, and `Player` finally derive from Movable. – Appleshell Jun 09 '14 at 04:00
  • @EvanCarslake, I would say *Movable* is a *property/behavior* of a player. So you can create a `Movable` *Interface* (actually abstract class in C++), and declare `TryMove()` an *pure virtual method*. Then inherit `Player` from `Movable` and define `TryMove()` in it. – Rakib Jun 09 '14 at 04:52
  • Updated Code: http://codepad.org/tqSrINRX Thanks for the reply. I have actually never dealt with virtual or abstract but I got this working, but still have to declare as moveable instead of player. Also, would I be declaring all things related to moving, as victuals? – Evan Carslake Jun 09 '14 at 05:19
  • 1
    @EvanCarslake, My design was to declare `Movable` as interface, and inherit (actually implement) `Player` from `Movable`. But you did the opposite. But your current design will be more accurate if you rename `Movable` to `MovablePlayer`. Then you can say `MovablePlayer` is a specialty of `Player` which can move. This makes sense in *not all player can move**. Check edited reply – Rakib Jun 09 '14 at 05:26
  • @EvanCarslake, it is better practice to put `override` keyword after overriden method names – Rakib Jun 09 '14 at 05:45
2

The way that I would recommend thinking of it is the Is A or Has A idiom. So... Is the Player a Move? Probably not, Is the Move A Player? also probably not. Then lets try the Has A. Does The Move Have a Player or Does the Player Have A move? I would Say that the Player Has a Move Personally. This would mean not using inheritance but rather having the player contain an instance of the Move class. So...

class Player{
public:
    Move myMove;//where move is defined already as whatever you need it to be.    
};

//then your main
int main(int argc, const char** argv){
    //...other setup here
    Player p;
    p.myMove.TryMove(10);
    //whatever else...
}

This is how i might approach your design. As far as the error... In the code above you had Move inherit from Player but you created a Player and expected it to have the functionality of Move but it would have no way of having that functionality based on the inheritance you set up in the example code.

Let me know if you need any clarification of what I have said or anything else. Good Luck

EDIT:

Based on your comment I would suggest that you use a wrapper function that will get the value that you need.

class Player{
public:
    void TryMove(int i);
private:
    Move myMove;
    int x;//the value you will be getting from Move::tryMove
};

void Player::TryMove(int i){
    this->x = myMove.tryMove(i);//store the value of the function call
    //the function obviously won't be a void function in this case
}

There are other ways you could do this but this way is simple. If you are set on using inheritance to solve your problem I would have Player inherit from Move, But I still stand by my original answer I just wanted to help explain further.

Alex Zywicki
  • 2,263
  • 1
  • 19
  • 34
  • Thanks. The design I am aiming for is for the Move class to be able to change values of the parent class. So I have a player, I call tryMove(), I need players x value to be changed. – Evan Carslake Jun 09 '14 at 03:55
  • @EvanCarslake I will write an edit to try and accommodate for that. I would probably suggest a wrapper function. – Alex Zywicki Jun 09 '14 at 22:10
  • Nice, that is exactly what I was looking for. Another question though. Is there any way that I could access a public/ protected variable from within the Move class? Such as to tryMove needs to know the player or items x, y, width and height variables. I suppose I could send those as parameters, but is there another way? – Evan Carslake Jun 09 '14 at 23:53
  • 1
    @EvanCarslake you could either send them as parameters or make the `Move` class a friend of the `Player` class, I would recommend just sending them as parameters because using friendship can be tricky and does not work well with inheritance. Try it as parameters and see if that works. – Alex Zywicki Jun 10 '14 at 00:00