Circular Inclusion using Singleton and child class - c++

While working on a little game of mine, I ran into a circular dependency related issue.
Say I'm using 2 classes and a helper namespace(all include guarded), where Base is the main game class, Player the player object and a child of Entity, and helper a functional namespace responsible for handling tile collision:
When I try to compile the code, Player is not recognized as a type-specifier in base.h and I also get an unknown override specifier. When I forward declare Player it is undefined, although I am including player.h.
I've been questing on the internet for a solution, but none of the typical solutions to circular inclusion seemed applicable. As aforementioned I have tried all sorts of combinations of forward-declarations but it only changed the type of error.
I was wondering whether anyone could notice any flaw in the code below.
(Please note that I've put all of the function implementations in the headers for demonstration purposes only, they've got their own little cpp files)
base.h
#include "player.h"
#include "level.h"
class Base{
static Base& instance()
{
static Base base;
return base;
}
Player player;
Level level;
}
entity.h
class Entity{
vec2 velocity; //Assume we are using the glm library
vec2 position;
virtual void update()
{
}
}
player.h
#include "helper.h"
#include "entity.h"
class Player:public Entity{
void update()
{
velocity=helper::tileCollision(velocity);
//Update position and stuff
}
}
helper.h
#include "level.h"
#include "base.h"
namespace helper{
vec2 tileCollision(vec2 velocity)
{
Level& level = Game::instance().level;
//Pop some fancy tile collision math in here
return vec2(0);
}
}

The first of all, please don't write implementations of functions in headers unless it is not inline or template.
Try the following:
base.h
#include <memory>
class Player;
class Level;
class Base {
public:
static Base& instance();
private:
Base();
unique_ptr<Player> player;
unique_ptr<Level> level;
}
base.cpp
#include "base.h"
#include "player.h"
#include "level.h"
Base::Base() : Player(make_unique<Player>()), Level(make_unique<Level>())
{
}
static Base& Base::instance()
{
static Base base;
return base;
}
And you should watch the following :
https://www.youtube.com/watch?v=QjFpKJ8Xx78

Related

c++ .h inclusion of classes and .cpp from one class passing through to another class

new to c++ having a hard time understanding when inherited classes break the compiler so I'm trying to construct a player class and pass it to the core class then use the core class to create the objects
errors:
./core.h:6:12: error: expected unqualified-id
class Core public: Player {
^
app.cpp:6:8: error: variable has incomplete type 'Core'
Core core;
^
./core.h:6:7: note: forward declaration of 'Core'
class Core public: Player {
app.cpp
#include "core.h"
int main()
{
Core core;
core.Player(..);
core.Player(..);
std::cout << core.GetStringValue(..);
}
Player.cpp
#include "core.h"
#include "PlayerKeys.h"
class Player {
private:
.... initialized variables
public:
... functions
One function calls a function from Core.Datetime
}
core.h
#ifndef Core_H
#define Core_H
class Core public: Player {
public:
...
};
#endif
core.cpp
class Core{
public:
std::string DevlopmentTeamAccessDailyHash(){
...
}
std::sting SystemAccessActiveHash(){
...
}
std::string CurrentDateAndTime(){
...
}
}
your core.cpp and player.cpp files contain the class declaration. they are not for class declaration. they should contain the class definitions.
for example your core.cpp should look something like this.
#include "core.h"
Core::Core()
{
//...
}
std::string Core::DevlopmentTeamAccessDailyHash()
{
//...
}
while your header looks something like this
#ifndef Core_H
#define Core_H
class Core : public Player //note that you place the : in wrong place
{
public:
Core();
std::string DevlopmentTeamAccessDailyHash();
...
};
#endif
Edit : you mentioned in comments you want to pass some arguments to the constructor of Player through Core
I assume this is what you wanted to do with this call.
core.Player(..);
this call is not a valid way to call the player constructor.
You could perhaps do core.Player::Player(your arguments) but this is again not how OOP works.
instead you modify the Core constructor so it takes all the parameters it needs
in header file (Core.h)
Core::Core(parameters ...);
in cpp file (Core.cpp)
Core::Core(parameters ...)
{
Player::Player(parameters passed as arguments...);
//do core stuff..
}
class Core : public Player {
Just put the colon before public. A simple syntactical error. Also don't forget to include player.h in your core.h (You may have to move the Player class declaration to a header file if it only resides in a .cpp-File).

Circular Inclusion and Inheritence with Forward Declarations Leads to C2504 base class undefined

I am getting a C2504 compilation error in PlayerController.h saying that my base class (Updateable) is undefined. I have searched for several hours for a solution to a circular inclusion with inheritance problem and their solutions are to remove the circular inclusions and jsut use a forward declaration. As far as I understand, this works if no methods from the forward declared class are called. However, in my program my Updateables class calls a method on its member inherited gameObject object and the GameObjects also call methods on their member Updateables. Because of this, Updateables need to include GameObject.h and GameObjects need to include Updateables.h. This leads to a C2504 in PlayerController.h saying that the base class Updateable can not be found.
Here are my relevant classes:
Component.h
#pragma once
#include "Vector3.h"
class GameObject;
class Component {
public:
GameObject* gameObject = nullptr;
Component();
};
Component.cpp
#include "Component.h"
Component::Component() {}
Updateable.h
#pragma once
#include "Component.h"
#include "GameObject.h"
class GameObject;
class Updateable : public Component {
public:
~Updateable();
virtual void update() = 0;
};
Updateable.cpp
#include "Updateable.h"
Updateable::~Updateable() {
if (gameObject) {
gameObject->removeUpdateable(this);
}
}
GameObject.h
#pragma once
#include "Updateable.h"
#include "GameManager.h"
class Updateable;
class GameObject {
public:
GameObject();
~GameObject();
void runUpdateables();
void addUpdateable(Updateable* updateable);
void removeUpdateable(Updateable* updateable);
private:
vector<Updateable*> updateables;
};
GameObject.cpp
#include "GameObject.h"
GameObject::GameObject() {
updateables = vector<Updateable*>();
GameManager::addGameObject(this);
}
GameObject::~GameObject() {
GameManager::removeGameObject(this);
}
void GameObject::runUpdateables() {
for (unsigned int i = 0; i < updateables.size(); i++) {
updateables[i]->update();
}
}
void GameObject::addUpdateable(Updateable* updateable) {
updateables.push_back(updateable);
updateable->gameObject = this;
}
void GameObject::removeUpdateable(Updateable* updateable) {
auto it = find(updateables.begin(), updateables.end(), updateable);
if (it != updateables.end()) {
updateables.erase(it);
}
}
PlayerController.h
#pragma once
#include "Updateable.h"
//#include "GameObject.h"
#include "Input.h"
class Updateable;
class PlayerController : public Updateable {
public:
float speed = 5.0f;
void update();
};
PlayerController.cpp
#include "PlayerController.h"
void PlayerController::update() {
float x = 0;
if (Input::getKeyDown(GLFW_KEY_A)) {
x = -speed;
}
if (Input::getKeyDown(GLFW_KEY_D)) {
x = speed;
}
cout << x << endl;
gameObject->getRigidBody()->velocity.x = x;
//yes this is a method in GameObject that I removed from this post
//because it would take up more space, rigidbody.h does not create
//a circular dependency
}
GameManager.h
#pragma once
#include "GameObject.h"
#include "PlayerController.h"
class GameManager {
public:
static void init();
static void addGameObject(GameObject* go);
static void removeGameObject(GameObject* go);
static void onFrame();
private:
static vector<GameObject*> gameObjects;
static GameObject* box;
GameManager.cpp
#include "GameManager.h"
vector<GameObject*> GameManager::gameObjects;
GameObject* GameManager::box;
void GameManager::init() {
gameObjects = vector<GameObject*>();
box = new GameObject();
box->addUpdateable(new PlayerController());
}
void GameManager::addGameObject(GameObject* go) {
gameObjects.push_back(go);
}
void GameManager::removeGameObject(GameObject* go) {
auto it = find(gameObjects.begin(), gameObjects.end(), go);
if (it != gameObjects.end()) {
gameObjects.erase(it);
}
}
void GameManager::onFrame() {
for (unsigned int i = 0; i < gameObjects.size(); i++) {
gameObjects[i]->runUpdateables();
}
}
Here is the exact error message: Error C2504 'Updateable': base class undefined Basic Platformer c:\users\default.sixcore-pc\documents\visual studio 2015\projects\basic platformer\basic platformer\playercontroller.h 9
A lot of your files have both #include "Class.h" and class Class; declarations. You never need both; use one or the other.
A definition of a class X must be visible when:
accessing the members of X
creating an object of type X
defining a class derived from X
using X as a template argument to a template which requires the corresponding template parameter to be a complete type (such as what standard library containers require of their element type). Note that this applies when using X, not X*.
In other cases (such as creating a pointer to X or declaring a function taking of returning X), a non-defining declaration (class X;) is enough.
Using these rules (plus moving function bodies from headers to source files when necessary), you can solve any circular dependency issues.
To directly address your files as presented:
Updateable.h does not need to #include "GameObject.h". It doesn't even need the forward declaration of GameObject.
GameObject.h doesn't need any of the two #includes in it.
GameManager.h doesn't need any #includes. It needs a declaration of class GameObject; though.
Descendant class must know the full definition of the base class. Forward declaration is not enough and useless.

Troubles with Circular Dependencies between 3 classes and with inheritance

I'm a first-year college student that doesn't know everything about CS yet, so please bear with my newness to it, and this is my first question on here.
For an assignment, we are making faux version of Pokemon Go to practice using polymorphism in c++, and I'm running into some compiler errors. Here are the three files with just a sample of the code in them:
#ifndef EVENT_H
#define EVENT_H
#include <string>
#include "Trainer.h"
class Event{
protected:
std::string title;
public:
Event();
~Event();
virtual void action(Trainer) = 0;
};
#endif
Trainer.h:
#ifndef TRAINER_H
#define TRAINER_H
#include "Pokemon.h"
class Trainer{
private:
Pokemon* pokemon;
int num_pokemon;
public:
Trainer();
~Trainer();
//include accessors and mutators for private variables
};
#endif
Pokemon.h:
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event{
protected:
std::string type;
std::string name;
public:
Pokemon();
~Pokemon();
virtual bool catch_pokemon() = 0;
};
#endif
The trainer.h file is a parent class for each pokemon type (eg Rock) which just defines a few virtual functions. The error I'm getting is when I'm compiling all of this and I get something that says:
Pokemon.h : 5:30: error: expected class-name befoer '{' token:
class Pokemon : Event {
Pokemon need to be a derived class to an event, so that an event pointer can point in another Location class can point to either a pokemon, pokestop, or cave for the assignment, and I have been looking online for hours and can't figure out what to do. I would appreciate the help! Let me know if you need more info or something because again, this is my first time posting a question.
You need some forward declarations.
In Event.h, you can put class Trainer; instead of #include "Trainer.h". In Trainer.h, you can put class Pokemon; instead of #include "Pokemon.h".
You will probably need to include the appropriate headers in the corresponding source files in order to actually use the other classes. But by avoiding the includes in the header files, you get out of the circular dependency trouble.
Pokemon.h must continue to #include "Event.h", since you're inheriting Event, which requires a complete definition.
Use forward declaration, to tell classes the type they need to use will be defined later. You can use forward declaration in situations where the size is know, pointers and references are always the same size regardless of the type they point to so use them.
#ifndef EVENT_H
#define EVENT_H
#include <string>
class Trainer;
class Event
{
protected:
std::string title;
public:
Event();
virtual ~Event();
virtual void action(Trainer* const trainer) = 0;
};
#endif
then
#ifndef TRAINER_H
#define TRAINER_H
class Pokemon;
class Trainer
{
private:
Pokemon* const pokemon;
int numPokemon;
public:
Trainer();
~Trainer();
};
#endif
then
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event
{
protected:
std::string type;
std::string name;
public:
Pokemon();
virtual ~Pokemon();
virtual bool catchPokemon() = 0;
};
#endif
when using polymorphism (virtual functions) you must always make the base class destructor virtual too. It is also nice to make the derived classes destructor virtual as well, but it is not required.

Keep getting "no member function declared" error, even though it is declared and defined

I have a fairly simple situation, and the fact that I can't cope with it drives me crazy.
I have a class that is declared as follows:
// inc/Services/Specific/ReviewRetriever.h
#include "../../ReviewRetriever.h"
class Specific_ReviewRetriever : public ReviewRetriever
{
public:
Specific_ReviewRetriever(Service* service);
~Specific_ReviewRetriever() = default;
};
Implementation of the class goes as follows:
// src/Services/TrustedShops/ReviewRetriever.cpp
#include <string>
#include <vector>
#include "Service.h"
#include "Services/Specific/ReviewRetriever.h"
Specific_ReviewRetriever::Specific_ReviewRetriever(Service* service) :
ReviewRetriever(service)
{
}
std::string Specific_ReviewRetriever::prepare_update_link(std::string link)
{
}
std::vector<int> Specific_ReviewRetriever::parse_response(boost::property_tree::ptree responseXML)
{
}
This class inherits from the class that is declared as follows:
// inc/ReviewRetriever.h
#include <string>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include "Review.h"
class Service;
class ReviewRetriever
{
public:
~ReviewRetriever() = default;
void retrieve(std::vector<Review> & reviews);
protected:
ReviewRetriever(Service* service);
virtual std::string prepare_update_link(std::string link) = 0;
virtual std::vector<Review> parse_response(boost::property_tree::ptree responseXML) = 0;
Service* _service;
};
And this class on its part is defined as follows:
// src/ReviewRetriever.cpp
#include <vector>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include "Review.h"
#include "ReviewRetriever.h"
void ReviewRetriever::retrieve(std::vector<Review> & reviews)
{
}
So a fairly simple class and another one that inherits from it. But when I try to compile the code I get the following error:
no ‘std::string Specific_ReviewRetriever::prepare_update_link(std::string)’
member function declared in class ‘Specific_ReviewRetriever’
So, even though I got implementation of the class, the compiler doesn't seem to notice it (even though it sees that the class Specific_ReviewRetriever inherits from ReviewRetriever, it refuses to recognize its methods).
I build with cmake and here is the relevant part:
// src/CMakeLists.txt
file(GLOB_RECURSE sources *.cpp)
target_include_directories(my_target PRIVATE ${PROJECT_SOURCE_DIR}/inc/)
(here ${PROJECT_SOURCE_DIR} is src/../).
So as I mentioned, implementation and declaration of the classes is present, and yet compilation fails. I understand that the problem may not be on the surface, but I am really clueless where to start to track the error, maybe you have a piece of advice on that.
In case this excerpt of code is insufficient, entire code lies here.
Thank you in advance!
You still have to declare the functions that you're overriding in the derived class:
class Specific_ReviewRetriever : public ReviewRetriever
{
public:
Specific_ReviewRetriever(Service* service);
~Specific_ReviewRetriever() = default;
// Overrides:
virtual std::string prepare_update_link(std::string link);
virtual std::vector<int> Specific_ReviewRetriever::parse_response(boost::property_tree::ptree responseXML);
};

C++ Method declaration using another class

I'm starting to learn C++ (coming from Java), so bear with me.
I can't seem to get my method declaration to accept a class I've made.
'Context' has not been declared
I think I'm not understanding a fundamental concept, but I don't know what.
Expression.h
#include "Context.h"
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
};
Context.h
#include <stack>
#include <vector>
#include "Expression.h"
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
};
You have to forward declare Expression in Context or vice versa (or both), otherwise you have a cyclic dependency. For example,
Expression.h:
class Context; // no include, we only have Context*.
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
};
Context.h:
#include <stack>
#include <vector>
class Expression; // No include, we only have Expression*
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
};
You can perform the forward declarations because the full definition of the classes isn't needed, since you are only referring to pointers to the other class in each case. It is likely that you will need the includes in the implementation files (that is, #include "Context.h" in Expression.cpp and #include Expression.h in Context.cpp).
Finally, remember to put include guards in your header files.
In C++, class definitions always have to end with a semi-colon ;
so example:
class foo {};
Java and C# doesn't require that, so I can see your confusion.
Also it looks like both your header files include each other. Thus it's kind of like a snake eating it's tail: Where does it start? Thus in your Expression.h you can replace the 'include' with a forward declaration instead:
class Context;
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
}
And last but not least, you should put a compiler guard to prevent the header from getting included more than once into a .cpp file. You can put a #pragma once in the top of the header file. That is useful if you are using visual studio and the microsoft compiler. I don't know if GCC supports it or not. Or you can wrap your header file like this:
#ifndef EXPRESSION_H_
#define EXPRESSION_H_
class Context;
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
}
#endif
you might need to forward declare the classes Context and Expression in the header files before the #include
e.g.
#include <stack>
#include <vector>
// forward declaration
class Context;
class Expression;
#include "Expression.h"
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
}