Stupid question probably, but I couldn't find the answer (even here).
I have split all my classes in separate files (cpp+h). I have methods like getValue() and setValue(). I have class called Player (this is basically the database with whole number of variables). I created an object called player (Player *player = new Player;). Now I need to access THIS object from any other class (that separated in another file). The problem is that I cannot even access getValue() / setValue() methods.
What I need is something like in Delphi From1.player.item[0]=3 access from form 2, where the player is recorded.
UPD:
Here's my code:
Player.cpp
#include "player.h"
#include "gameform.h"
Player::Player()
{
}
void Player::check(){
//I should be able to check if player dead or not from my Battle class
}
player.h
#ifndef PLAYER_H
#define PLAYER_H
class Player
{
public:
Player();
void check();
};
#endif // PLAYER_H
Battle.cpp
#include "battle.h"
#include "player.h"
#include "game.h"
Battle::Battle()
{
}
void Battle::hit(){
//if I hit I should check am I dead yet
player.check();
}
That's how Player declared in Game class (now):
Player *player = new Player;
Outside of any functions, just in class.
Where player is object, created in Game class. All things are public.
*I've tried even creating object in main.cpp (both in and out of main() function), and nothing working, weird =/
This is github "temp" branch, compiling and working. But how to access player? :)
https://github.com/ewancoder/game/tree/temp
UPD: Another stupid question: If I want that in my class 1 function is responsible for opening file and another - for editing and closing file, how can I do that if one cannot read vars from another?
I'm not sure what you want, but if you have a class like this:
a.hpp
Class A {
public:
void foo();
};
a.cpp
#include "a.hpp"
void A::foo() {}
You can use it like this:
b.hpp
#include "a.hpp"
class B {
public:
void stuff(A& a);
};
b.cpp
#include "b.hpp"
void B::stuff(A& a) { a.stuff(); }
You need to give the other object the reference of the first. Either direct in the constructor or later via a method.
Or alternativly you could store player in a global variable and access it via the global variable.
The problem is that the methods are bound to the specific instance of the object - and so you need that instance to call them
You need to add parenthesis to the end of the statement and use the -> operator, not the . operator: player->check()
This is because it is a pointer to an object Player *player and not an object itself Player player
Your question is a little hard to follow, and some of the answers reflect that. However, in my view what you are running into is actually a critically important part of your system design. There are many strategies, and many considerations, but basically it's up to you to design the paths by which objects can access the contents of other objects in your running program.
Some common techniques include
Global variables
extern Player *PlayerOne;
PlayerOne->item[0]=3;
Static variables (or collections) in the class.
class Player {
public:
Player* Players;
}
Player::Players[0]->item[0]=3;
Member variables.
Board.Add(new Player(Board));
Board.m_player->item[0]=3;
The variations are endless. You'll need to be more specific if you want specific code.
Related
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 2 years ago.
So, I know that there are many questions on stack overflow out there that are trying to handle circular dependencies. But none of those could really answer my question, if it is possible to have two classes know each other, and, more importantly, access information from each other. So, basically, I have read that you could use forward decleration, but with forward decleration, I couldn't access any fields. Maybe I should also add that I am really new to C++.But enough talking, let's get to an example:
Let's say we have a class called Scene and a class called EntityBase, which are defined as following:
EntityBase.h
#pragma once
#include <string>
#include "Scene.h"
class EntityBase
{
public:
std::string entityId;
Scene scene;
EntityBase(std::string entityId);
/*
This method will be called when this object is added to the scene
*/
void onAddedToScene(Scene* scene);
/*
This method will be called when this object is removed from the scene
*/
void onRemovedFromScene(Scene* scene);
};
Scene.h
#pragma once
#include <vector>
#include <string>
#include "EntityBase.h"
class Scene
{
public:
std::vector<EntityBase> entities;
std::string name;
Scene(std::string name);
void addToScene(EntityBase& entityBase);
};
The question arises,
How can I print out the name of Scene(and use every method of Scene) while EntityBase can fully access Scene too?
So, I'd really appreciate if you'd tell how to do this, because I will probably need to access every field and/or method later.
Since the C++17 standard you don't need the full EntityBase class definition for the Scene class, only a forward declaration:
#pragma once
#include <vector>
#include <string>
class EntityBase; // Forward declaration
class Scene
{
public:
std::vector<EntityBase> entities;
std::string name;
Scene(std::string name);
void addToScene(EntityBase& entityBase);
};
You of course need to include EntityBase.h anywhere where the entities vector is used, most notable in the Scene.cpp source file.
Since EntityBase is using an actual instance of Scene you can't do the same with that class and the EntityBase.h header file. Here you must include the Scene.h header file.
If you build targeting an older C++ standard (C++14 or earlier) then you must have the full definition of the EntityBase class for the vector.
As a possible workaround either make entities a vector of pointers to EntityBase; Or make EntityBase::scene a pointer and use forward declaration in the EntityBase.h header file instead. Or a combination of both.
This question comes from this question.
Im trying to implement the state pattern with a shared_ptr to the container(game).
However I have a problem with circular inclusion and need to forward declare.
My code:
Game.h
#pragma once
#include <memory>
#include "BaseState.h"
class Game : public std::enable_shared_from_this<Game>
{
private:
std::shared_ptr<BaseState> currentState;
public:
Game();
void switchState(std::shared_ptr<BaseState> nextState);
void doSomething(char);
void runState();
};
cpp
#include "stdafx.h"
#include <iostream>
#include "Game.h"
#include "SomeState.h"
Game::Game()
{
currentState = std::make_shared<SomeState>();
}
void Game::switchState(std::shared_ptr<BaseState> nextState)
{
currentState = nextState;
}
void Game::doSomething(char c)
{
std::cout << "Game : " << c;
}
void Game::runState()
{
currentState->handleCommand(shared_from_this());
}
BaseState.h
#pragma once
#include <memory>
#include "Game.h"
class BaseState
{
public:
virtual void handleCommand(std::shared_ptr<Game>) = 0;
};
SomeState.h
#pragma once
#include "BaseState.h"
class SomeState :
public BaseState
{
public:
// Inherited via BaseState
virtual void handleCommand(std::shared_ptr<Game>) override;
};
cpp
#include "stdafx.h"
#include "SomeState.h"
void SomeState::handleCommand(std::shared_ptr<Game> game)
{
game->doSomething('S');
}
I read other questions about forward declaring but still don't get it.
What I tried;
forward declare BaseState in Game, the code compiles but throws an error.
Unhandled exception at 0x73E9DAE8 in ConsoleApplication1.exe:
Microsoft C++ exception: std::bad_weak_ptr at memory location
0x00BBF5D4.
Forward declare Game in BaseState. Dosnt compile gives use of undefined type error, also
'doSomething': is not a member of
'std::shared_ptr'
which is logic because at compile time game has not a doSomething function because forward declared like;
class Game;
How do I decide where to forward declare another class, are there any logical steps or should I just pick one and fix the problems that choise creates?
You don't need to #include <Game.h> in BaseState.h, you can simply forward-declare it
class Game;
This works because the BaseState declaration doesn't need to know the contents of Game. So what you tried first is OK. The same applies to #include <BaseState.h> in Game.h. Replace that with a forward-declaration of BaseState.
The std::bad_weak_ptr exception was due to something else. Specifically, you're probably missing the little detail about shared_from_this, which says
It is permitted to call shared_from_this only on a previously shared
object, i.e. on an object managed by std::shared_ptr. Otherwise the
behavior is undefined
and
(from C++17) std::bad_weak_ptr is thrown (by the
shared_ptr constructor from a default-constructed weak_this)
You can usually solve this by instantiating your object into a shared_ptr:
int main() {
auto myGame = std::make_shared<Game>();
. . .
myGame->runState();
. . .
}
EDIT
Keep in mind though, that shared_ptr has a certain cost associated with using it. In general, if you know the pointed-to object always outlives the function call where it is used, as might be the case with your BaseState::handleCommand, then it may be faster (and still safe) to just pass it by reference.
My game has a Player class which is a player, controlled by the user and it will wield a weapon. The weapon class is in a different header file but contains a reference to the player, so it can tell the Player class what animation it has to use.
Now my question:
It seems that im doing something wrong with referencing to eachother. I have created a forward decleration in both header files, but i get an error: "incomplete type not allowed"
I also get "cannot convert from Player* const to Weapon" because i use this: m_weapon(Weapon(this)), that was a tryout to solve the problem.
my files:
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "DrawableObject.h"
#include "PlayerState.h"
class Weapon;
class Player : public AnimatableObject
{
private:
std::string m_name; //name of the player
States::PlayerState m_state; //state of the player
Weapon &m_weapon;
public:
Player(std::string name):
AnimatableObject("../../Images/PlayerSheet.png",
sf::Vector2i(64,64),sf::Vector2i(8,8)),
m_name(name),
m_weapon(Weapon(this))
{
m_updateTime = 100;
}
//Update the Player
virtual void Update() override;
};
#endif
Weapon.h
#ifndef WEAPON
#define WEAPON
#include "DrawableObject.h"
class Player;
class Weapon : AnimatableObject
{
protected:
float m_cooldown;
Player *m_user;
public:
Weapon(Player *user):m_cooldown(0.0f),
m_user(user),
AnimatableObject("",sf::Vector2i(0,0),sf::Vector2i(0,0))
{}
Weapon(Player *user, float f):
m_cooldown(f),
AnimatableObject("",sf::Vector2i(0,0),sf::Vector2i(0,0)),
m_user(user)
{}
virtual void Use(){} //Left Click/Trigger
virtual void AltUse(){} //Right Click/Trigger
};
#endif WEAPON
So how do i refer to eachother and dealing with the header files?
PS. im using Visual Studio 2012 if it helps
There are a few problems with your code:
m_weapon(Weapon(this))
When you do it, you're trying to construct a new Weapon object. But at this stage, it has not been defined yet (only forward declared). Try moving the constructor's implementation to your .cpp file, where you have included the Weapon.h file.
Anothre problem is that m_weapon is a reference to a Weapon object. When you do m_weapon(Weapon(this)), you're trying to contruct a new object, pass a reference to it and immediately destroy it, as it's a temporary. You can't do that.
What you can do is change m_weapon to be a pointer and initialise it with new Weapon(this). You then have to remember to destroy it in Player's destructor.
I this scenario it is important to establish which object owns the other. I this case Player would own the Weapon object and it would be it's duty to manage it (delete when appropriate).
A chest is composed of treasure.
I've implemented it the following way:
treasure.hpp
#pragma once
class Treasure{
public:
protected:
private:
//data members
int gold;
};
chest.hpp
#pragma once
class Chest{
private:
#include "treasure/treasure.hpp"
public:
protected:
private:
//data members
Treasure treasure;
};
**Assume both header files get compiled with their corresponding ".cpp"s to create object files.*
Is it appropriate to include the header file for treasure inside the class declaration of chest?
It makes sense to me, because I get the following behaviour:
**Main can not create or directly access Treasure.*
#include "chest.hpp"
int main(int argc, char** argv){
Chest chest;
}
I've never seen it this way, so I'm not sure if it is bad practice.
In regards to composition, which method is preferred:
including the header before the class declaration; having main indirectly include Treasure?
including the header privately inside the class declaration as shown above?
I would #include "treasure.hpp" at the top of chest.hpp before the Chest class declaration.. Not all treasure is found in a chest. If main() wants to create a Treasure that is not in a Chest, it should be allowed to do so.
On the other hand, I certainly can imagine times where a private class would be useful. In such a situation, I would code the private class directly inside the outer class rather than #include it.
I would have main include the file indirectly (treasures include is at the top of chest). It does not make very much sense to have multiple includes. In fact, that's one of the main uses of those precompiler directives; to prevent compilation errors due to a file being included multiple times.
If you do it the other way you couldn't do things main like; create new treasure and add it to your chest or take treasure out of your chest and work with it independently. That implementation would only make sense if the object B was used exclusively by object A.
I need to call properties and functions of an object from a different class.
The idea is passing 'this' as a parameter to the other class constructor. E.g.:
instance = ClassName(this);
And then do:
ParentClass parentInstance;
ClassName::ClassName(MainApp _instance){
parentInstance = _instance;
}
However, my compiler says that ParentClass does not name a type. Ideas?
Also, should I use a pointer to save memory? How?
Thanks in advance.
UPDATE:
Ok, sorry for the delay. Here it goes the actual code. First, a simple class.
Game class:
Header file
#ifndef _GAME
#define _GAME
#include "ofMain.h"
class Game{
public:
Game();
~Game();
void hi();
};
#endif
cpp file:
#include "Game.h"
Game::Game(){}
Game::~Game(){}
void Game::hi(){
cout << "hi, I'm game! " << endl;
}
Then, from MainApp I create the object:
- Relevant code on header file:
#ifndef _MAIN_APP
#define _MAIN_APP
#include "ofMain.h"
#include "Game.h"
class MainApp : public ofSimpleApp{
public:
Game game;
};
#endif
Relevant code on the cpp file:
game = Game();
game.hi();
This obviously works as I'm only creating a bloody object. However, problem comes with composition.
I could pass the main app as argument in the constructor, I could pass it via game.setParent(this);... problem is, I can't even define the variable to store the reference to the app.
E.g.: (making it easy/inefficient without pointers or anything)
Game.h:
#define _GAME
#ifndef _GAME
#include "ofMain.h"
#include "MainApp.h"
class Game{
MainApp app;
public:
Game();
~Game();
void hi();
};
#endif
This returns a "does not name a type" error and declaring class MainApp returns an "incomplete type" error
I'm sure I'm doing something dumb.
UPDATE 2:
The problem with that method is that I can't call a function of the pointed object now.
This is Game.h:
#ifndef _GAME
#define _GAME
#include "ofMain.h"
class MainApp;
class Game{
public:
Game();
Game(MainApp* _app);
~Game();
void hi();
MainApp* app;
};
#endif
As you see, app (of the type MainApp) is passed as a parameter. That's fine, MainApp exists as it's the forward declaration. However, when I try to call any of app's functions I can't (compiler error saying Request for member appHi in .... which is non-class type 'MainApp'.
MainApp is NOT included in Game.h but Game.h IS included in MainApp.h.
Ideas?
The problem is you have a circular reference - Game includes MainApp, and MainApp includes game. You need a 'forward declaration', as per the example by DeadMG.
See here.
It's called composition and is a common pattern. It's highly efficient in both semantics and in terms of runtime speed/memory footprint.
Your code example is a little too much pseudocode for me to read it correctly. Let me show you how it's done.
class X;
class Y {
...
void DoSomething(X* x, ... args);
};
class X {
Y y;
void DoSomething() {
y.DoSomething(this, args);
}
};
I think there may be two issues here:
1) You need to declare the ParentClass (i.g. #include its .hpp-file) before using it
2) The assignment "parentInstance = _instance" will invoke the assignment operator, which i'm guessing is not what you want. let "parentInstance" be a pointer instead.
Note the section on "#include."
http://www.cplusplus.com/doc/tutorial/program_structure/
After the "Intro to the C++ Language" section look for the verbiage about #include.
http://www.cprogramming.com/tutorial/lesson1.html
Namespaces:
http://www.tenouk.com/Module23.html
HTH
That's not how things work in C++. Unlike javascript, you cannot inject methods or fields into existing objects at runtime.
Madsen is on the right track here, but we need more code; What is the class heirarchy of ParentClass, ClassName and SaleraApp. Which classes are base and/or dervied?
When you write: parentInstance = _instance; the compiler will try to generate a default copy constructor if one is not defined. Your problem might be that you are trying to create a dervied class object from a base class pointer.
Also, "this" is a pointer.
If all you need to do is use functions and data members of another class, read up on the friend keyword. It will allow access to class members from other classes.
UPDATE: Alternatively, store a pointer or reference to the object you need access to, and make getters for data members and make the functions public... but I get the feeling this is not what you're after...