(C++) Pointers to Pointers of objects in different classes - c++

everyone. I'm working on a final project for school and it's coming along great, but I've run into a bit of a problem with trying to use a pointer to a pointer. I'll do my best to explain the problem below:
So I have a class called Player that sort of looks like this:
class Player
{
Player();
int health;
void adjustHealth(int);
};
Player::Player()
{
health = 40;
}
void Player::adjustHealth(int adjust)
{
health += adjust;
}
I have another class called Shelter, that include "Player.h" and looks a little like this:
class Shelter
{
Shelter();
Player* player; // Create a pointer to Player class.
};
In the Shelter header file, I have the following in my default constructor:
Shelter::Shelter()
{
...Other code here.
player = new Player();
}
In the Shelter header file, I use this new player for things like:
player->adjustHealth(-1); // Subtract one health from the player.
Which works great.
The problem I'm facing is with creating another class called Church, that is in a separate header file and acts as a separate location in the game. I want Church to use the same player that Shelter does, so it has all of the same stats, etc, rather than creating a new player in Church (which is what I did in Shelter.h).
Right now, I have something like:
class Church
{
Church();
Shelter **cplayer; // This is supposed to be the pointer to the pointer.
};
The default constructor is where I'm having my problem. I want to use the same player from Shelter, not create a new player like I did in Shelter.
Church::Church
{
What should I do here?
}
I've tried a number of things, but I can't quite get it working. Eventually I want to be able to do something like this:
player->adjustHealth(-1); // Subtract one health from the player.
Only in Church, so that player's stats, like health, are adjusted no matter which location they are in.
I hope my question makes sense. If not, I can try to clarify better. Anyway, thanks in advance.

The problem I'm facing is with creating another class called Church, that is in a separate header file and acts as a separate location in the game. I want Church to use the same player that Shelter does, so it has all of the same stats, etc, rather than creating a new player in Church
This sounds like an ideal situation to use std::shared_ptr.
class Shelter
{
Shelter();
std::shared_ptr<Player> player; // Create a pointer to Player class.
// Provide a public accessor
public:
std::shared_Ptr<Player> getPlayer() const { return player; }
};
and
class Church
{
Church(std::shared_ptr<Player> pl) : player(pl) {}
std::shared_ptr<Player> player;
// You haven't explained in your post why you need this.
// Maybe you don't need it.
// Shelter** shelter;
};

Related

C++ parent method access to child pointers

I'm pretty new to C++ and I am working in a little roguelike game. I have a generic class named Actor, which has 2 child classes, NPC and Player. The idea is for each child to contain specific data, such as experience provided by killing an NPC or the Player's stats, and special methods. On the other hand, Actor contains general methods such as move, because both player and NPC should move.
Now I have a vector of NPC pointers, and my move method should check if the target tile is occupied by an NPC (and some other NPC info), but I don't have access to that class from Actor. I added a forward declaration to NPC inside of Actor, but then I get this error:
pointer to incomplete class type is not allowed
because forward declaration is not enough to access NPC methods.
Actor.h:
class NPC; // Forward declaration.
class Actor
{
public:
void move(std::vector<std::unique_ptr<NPC>> & NPCs);
}
Actor.cpp:
void Actor::move(std::vector<std::unique_ptr<NPC>> & NPCs)
{
// Go through the NPCs.
for (const auto &NPC : NPCs)
{
if (NPC->getOutlook() > 0) ... // Error.
}
}
I could put the move method inside both NPC and Player, but I would be duplicating code, and that's a pretty bad idea.
What would be the best solution here? I guess there is a better way to organize this, but it seems pretty logical as it is. Maybe some kind of inheritance or virtual functions magic?
Thanks! :)
You will need to include the header where NPC is defined in Actor.cpp, otherwise the definition of NPC will be missing.
// Actor.cpp
#include "NPC.h"
void Actor::move(std::vector<std::unique_ptr<NPC>> & NPCs)
{
// Go through the NPCs.
for (const auto &NPC : NPCs)
{
if (NPC->getOutlook() > 0) ... // Now you'll be able to access this.
}
}

Accessing child function, while using parent class

I am doing an assignment for the university course and me and my partner have a problem. Program we are making is a game.
We have several classes, which all inherit from the base class, called Creature. These are all enemies player needs to deal with and they all run their own AIs. There are 4 different types of child classes, all within namespace Creature(Including parent, Creature), with one class having special functions that only it needs. This class is called Bunny.
Now, my job is to call AI functions as needed. Problem is, I do not always know what class I am calling out, as such, when I ask the game board to tell me what Creature I get.
All enemies are saved as pointers like so, in game board squares:
struct Square
{
// Pointers to Morso class, where the enemy is saved
Creature::Creature* creature;
//Undeeded stuff removed
};
Now, this is all and fine until we need to access to special functions. Pupu will multiply if certain conditions are filled. As such, with in Pupu there are few functions I need to call to make sure it carries out it's act correctly.
However, here comes the problem.
I call our board class to give me the creature that is in the coordinates I give to it.
void GameEngine::GameEngine::runAI()
{
Creature::Creature* creature= NULL;
for(unsigned int y = 0; y < dimY; y++)
{
for(unsigned int x = 0; x < dimX; x++)
{
Coordinate target;
target.setX(x);
target.setY(y);
creature= board_->returnCreature(target);
//If there is a creature in the target, run its AI
if(creature!= NULL)
{
//If it is, check special procedures
if(creature->returnType() == "bunny")
{
bunnyReproduce(creature);
}
creature->ai();
}
}//for x
}//for y
}
Now, :
void GameEngine::GameEngine::bunnyReproduce(Ccreature::Creature* creature)
{
//Checks that it really is a bunny
if( creature->returnType() != "bunny"){ return; }
//Check is there another bunny near
creature->checkForMate();
}
The problem is, creature, at this point, can't call for checkForMate, which is public member of Bunny, but not Creature. Do we need to make virtual function into Creature?
I tried making checkForMate into Creature::Bunny, but since the original value I try to give to it is Creature class, I can't do so. Do we need to to create an empty virtual function in Creature class and then override it it Bunnyclass?
I am running Qt Creator 2.7.0, with QT 5.0.2.
You should add virtual function reproduce to Creature class and implement it in Bunny or any other creature you may later add to the game. So that any creature will reproduce itself in it's own way. You don't even need to check creature type in this case. Since if you have some non reproducible creatures, you may just implement reproduce as empty method that will do nothing.
Ideally, your engine shouldn't need to care at all what kind of creature it's working with.
If you want the bunny to reproduce on each ai() step, why not do it in the bunny's ai()?
After all, shouldn't it be the bunny's responsibility to decide when to reproduce, rather than some almighty external Engine?
void Creature::Bunny::ai()
{
if (niceMateNearby())
reproduce();
else
eatCarrotsAndJumpAround();
}

Redundant code in composition class C++

I'm trying to pick up C++. Everything was going well until my 'practice' program hit I very minor snag. That snag, I believe, stems from a design issue.
Think of Blackjack(21). I made a few classes.
Card
Deck
Hand
Player
A Deck consists of - for simplicities sake - Has An array of cards.
-It can show all it cards
-It can shuffle
-It can remove cards
A Hand Is A Deck -with the benefit of
-It can calculate its hand value
-It can add Cards to the hand
Now to get to my issue - the Player design
-A Player Has A hand (private access)
My problem with player, is that hand has a method function called addCardToHand. I feel a sense of redundancy/bad design if I have to create a Player method called addCardToHand(Card c) in which calls and passes to the same method in hand.
or
declare Hand h as a public accessible member and in 'main()' do something like
Player p;
Card aCard;
p.h.addCard(aCard);
Any advice would be enlightening and highly appreciated. Keep in mind I am learning.
The best answer here is: it depends :) I'll try to clarify it a little, though.
The first question is: does the Player class have any inner logic? If it's a simple container for Hand, I'd simply write Player.GetHand().AddCard(), because there is no reason to duplicate the code inside Player.AddCard() method, and the problem is solved.
Let's suppose now, that there is a need for implementing additional logic for adding a card to Player's hand. That means, that additional code in Player class has to be called while adding a card to Hand. In such case, I see three possible solutions.
(Sources only for demonstration purposes, may not compile)
Restrict access to Hand, such that no one can retrieve it from Player. Player would have to implement methods like AddToHand, RemoveFromHand etc. Doable, but not comfortable to use.
class Player
{
private:
Hand hand;
public:
void AddToHand(Card & card)
{
hand.Add(card);
}
};
Use the observer pattern. When user (class user) calls Player.GetHand().AddCard(), Hand notifies Player, that data has changed and Player can act accordingly. You can achieve this quite easily using std::function from C++11 to implement events.
class Deck
{
private:
std::function<void(void)> cardsChanged;
public:
void Add(Card card)
{
// Add a card
if (!(cardsChanged._Empty()))
cardsChanged();
}
void SetCardsChangedHandler(std::function<void(void)> newHandler)
{
cardsChanged = newHandler;
}
};
// (...)
class Player
{
private:
Hand hand;
void CardsChanged() { ... }
(...)
public:
Player()
{
hand.SetCardsChangedHandler([&this]() { this.CardsChanged(); } );
}
};
Define IHand interface with all necessary interface methods. Hand should obviously implement IHand and Player.GetHand() should return IHand. The trick is, that the IHand returned by Player do not necessarily have to be a Hand instance, but instead it can be a decorator acting as a bridge between user and real Hand instance (see decorator pattern).
class IHand
{
public:
virtual void Add(Card card) = 0;
virtual void Remove(Card card) = 0;
};
class Hand : public IHand
{
// Implementations
}
class PlayersHand : public IHand
{
private:
Hand & hand;
Player & player;
public:
PlayersHand(Hand & newHand, Player & newPlayer)
{
hand = newHand;
player = newPlayer;
}
void Add(Card card)
{
hand.Add(card);
player.HandChanged();
}
// ...
};
class Player
{
private:
Hand hand;
PlayersHand * playersHand;
public:
Player()
{
playersHand = new PlayersHand(hand, this);
}
IHand GetHand()
{
return playersHand;
}
}
Personally, In the second case, I would choose the second solution - it's quite straightforward and easy to extend and reuse in case of further needs.
Function call forwarding is a common practice. You should think about it as adding some level of abstraction. This is not exactly doing the same thing again (which redundancy would mean), but implementing one method, using another one.
You can imagine some modifications in the future, like adding Player's cards cache, or some other stuff that need to be updated when user call addCardToHand. Where would you add the cache-updating code if you didn't implement the forwarding method?
Also note, that the "interface" of Player::addCardToHand doesn't need to be identical with Card::addCard i.e. arguments and returned value can be different in these functions. Maybe in this case it's not so important, but generally the forwarding function is the place where some translation between Player's interface and Hand's interface may be added.

Is it possible to initialise two classes, that require pointers to each other, at the same time?

I am making a snake game. I have two classes, snake and food. When I call snake->move() it needs to check that there are no collisions and for this purpose it needs to know what food's position is and therefore requires a pointer to food. food has a function that moves it to a new random position, move->setNewPosition(), which needs to know the position of snake so that it doesn't collide with the snake when it moves. For this purpose, it requires a pointer to snake.
Therefore, for both classes, I would need to supply a pointer to the other class which must be initialised. But to initialise the other class I need to initialise the other class and so on. Is there any way to initialise two classes, that require pointers to each other, at the same time?
If not, what would be a better way of structuring my program that would allow me to check the coordinates of the other class?
If i don't misunderstand you, create init function that call before game loop starts:
void initSnake()
{
auto snake = new Snake();
auto food = new Food();
snake->setFood(food);
food->setSnake(snake);
}
They just need the facility to find the location of other snakes and food items when their movement functions are invoked. There's no need to know of their existence at initialisation time!
You can therefore have a collection of snakes and a collection of food items, and pass a reference to those collections to any newly created snakes and food items. Just create those collections first.
You could do this via another class, perhaps, which could also act as a factory.
class GameManager;
class Snake
{
friend class GameManager;
public:
int getX() { return _x; }
int getY() { return _y; }
void setPosition(int x, y) { /* ... */ }
private:
Snake(GameManager* manager, int x, int y) : _manager(manager), _x(x), _y(y) {}
GameManager* _manager;
int _x, _y;
};
class GameManager
{
public:
const std::vector<Snake*>& Snakes() { return _snakes; }
Snake* SpawnSnake(int x, int y)
{
Snake* newSnake = new Snake(this, x, y);
snakes.push_back(newSnake);
return snake;
}
private:
std::vector<Snake*> _snakes;
};
(Just an example. Code not tested to see if it actually compiles. E&OE)
The GameManager ensures that all created snakes are found in the snakes vector because the Snake constructor is private. Each snake can call _manager.Snakes() to get a vector containing all the other snakes in the game which it can then query individually for their positions. This is easily generalised to support food items as well.
This has the small advantage over the "construct-initialise" pattern suggested in other answers in that it ensures that when you get a new Snake object it is actually ready for use... this example isn't quite RAII, but it would require a minimum of effort to make it reasonably exception-safe.
You can define one base class for them, which has these methods:
virtual void setPosition(const int x, const int y)
virtual void getPosition(int &x, int &y) const
Snake should use them too, just override them if you need to. Now both classes can call each other's setPosition and getPosition directly if you give the other object as a parameter with type Base.
An other way would be; In your main()-function, or wherever you define your snake:
int main()
{
Snake* s = new Snake;
Food* f = new Food;
Snake->setLocation(0,0); // Wherever you want the snake to start from
}
And whenever you create a new food, give it snake's location: f->setRandomLocation(snake->getLocation()) where the parameter would be coordinates where NOT to place it.
One alternative would be to have a Manager class which both of them send their requests to, which would make more sense (but doesn't solve your particular problem).
Nevertheless, if you have class A and class B, and each one needs the other, you can do the following:
A *a = new A;
B *b = new B;
// check a and b to make sure they are not NULL
a->set_b(b);
b->set_a(a);
Mmn, not sure how your game works but I assume there would be a lot of food objects?
Maybe an idea would be to create a Collision class that accepts a Snake player and stores all the Food players in the game.
So the Collision constructor might look like this
Collison(Snake &snake, Vector<Food*> &foods)
{
}
The Collision class would also have an collision update to loop that you call somewhere in your code.. This loop would check if the snake object collides with a food object.. and you can do whatever you want.. remove the food from the foods vector change the food position, whatever.
collison.UpdateCollisions() ;
I would suggest breaking the cyclic dependency, instead of hammering it in: make both moving functions take the environment (i.e. a list of things it can collide with) as a parameter.

Children Accessing Elements of Other Children of the Same Parent

I'm currently developing an RPG game using C++ and I got to the point of including events on the map.
I wanted to be able to have the event on the map heal the player. I figured the easiest way to do this was to pass a pointer to the event object from the game using the 'this' keyword. When I got into doing this there were a whole bunch of compiler errors that seem to have resulted from trying to include a class that was currently attempting to include the other class. (endless loop I guess?)
For example. I have my 'game' class and it has a public member belonging to the 'mapManager' class. The 'mapManager' object then has the 'event' object as a member. The 'game' object also has a 'player' object within its' members. I need to have the 'event' object change variables that the 'player' has. I could honestly throw pointers whenever I need them but this might get cumbersome.
What I'm trying to ask is if there is an easy way to have a child of a parent access another child of that parent or if it would just be easier to throw pointers to all of the child classes needing them pointing to the other children.
Wow... that made very little sense but hopefully someone can understand enough to give me a good answer. Here's some code in case it helps.
:game.h
include "player.h"
include "event.h"
class game
{
public:
player Player;
event Event;
};
:player.h
class player
{
public:
game* Game;
};
:event.h
class event
{
public:
game* Game;
};
Having just this results in "game does not name a type" and so I tried to include game in event.h and player.h and got the same error. What I want to do is be able to access player's variable HP from inside event.
It's preferable to avoid circular references where possible; however if you really want to do that, then the solution is to forward-declare your class Game at the top of the header files which will be using references/pointers to it. e.g.
#ifndef EVENTH
#define EVENTH
class Game;
class Event
{
Game* game;
};
#endif
and..
#ifndef PLAYERH
#define PLAYERH
class Game;
class Player
{
Game* game;
};
#endif
For header files which need no knowlege of the implementation/sizeof the Game class, a simple forward-declaration is sufficient to let the compiler know that a class with that name exists.
In your .cpp source files (where the implementation of Game is actually important and used by Player/Event implementation) you will still need to #include the header containing your Game class definition.
//game.h
class event;
class game {
event _e;
private:
game(){}
//game& operator=(game& other) {}
~game(){}
public:
static game & getInstance() {
static game instance;
return instance;
}
event& getEvent() {return _e;}
};
//HealEventObserver.h
class HealEventObserver {
public:
virtual void heal() = 0;
virtual ~HealEventObserver(){}
};
//player.h include game.h and HealEventObserver.h event.h
class Player : public HealEventObserver
{
public:
virtual void heal() {/*heal the player*/}
Player() {
game& instance = game::getInstance();
event& e = instance.getEvent();
e.registerObserver(this);
}
};
//event.h include HealEventObserver.h
class event {
std::set<HealEventObserver*> _observers;
void notify() {
std::set<HealEventObserver*>::iterator it = _observers.begin();
std::set<HealEventObserver*>::iterator end = _observers.end();
for( ;it!=end; ++it) {
it->heal();
}
}
public:
void registerObserver(HealEventObserver* observer) {_observers.insert(observer);}
};
Don't make your event object change the player at all just make the event tell the player to heal himself. Also if game is suppose to represent everything then make it global.
To Answer the comment: (This is just my opinion and nothing else.)
After a bit of research i found this link that gives the names of great references.
The Definitive C++ Book Guide and List