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).
Related
How to solve this problem?
Just getting following errors:
g++ output:
duplicate symbol _game in:
/var/folders/w6/yqp0s0t92hl5g842hg8tztfr0000gn/T/main-62666f.o
/var/folders/w6/yqp0s0t92hl5g842hg8tztfr0000gn/T/Game-a5a31d.o
duplicate symbol _game in:
/var/folders/w6/yqp0s0t92hl5g842hg8tztfr0000gn/T/main-62666f.o
/var/folders/w6/yqp0s0t92hl5g842hg8tztfr0000gn/T/Write-83f8ee.o
It seems like the problem is not in the header files.
EDIT: Header files look like this:
#ifndef GAME_H
#define GAME_H
#include "Color.h"
#include "Tile.h"
class Game
{
public:
Game();
~Game();
Color getActivePlayer();
void setStarttile(Tile Firststarttile);
Color togglePlayer();
void setRunning(bool run);
char newActiveplayer;
void run();
void runsecondmethod();
private:
Game(const Game &);
Color Activeplayer;
Tile *Starttile;
bool Running;
}game;
#endif
You have instantiated a Game instance in your header file "Game.h", and since this is being included in multiple files you end up with multiple instances of game at link time. Change:
class Game
{
public:
...
}game;
to:
class Game
{
public:
...
};
extern Game game;
and then add:
Game game;
in one of your .cpp files.
In your header file (the one included from Write.cpp and GameBoard.cpp), you're likely to have an instantiation instead of a declaration.
Common cases/pitfalls :
missing extern before global variables
having function implementation (i.e. having void foo(Bar& b) {} instead of void foo(Bar& b);
Without more details, hard to help...
Look for where addnewtile function is defined for example...
EDIT
With more details
class Game
{
(zip)
}game;
This is declaring the class Game and creating a game object each time you include the header file.
Use
class Game
{
(zip)
};
In the header file and Game game; in the cpp
Or use a singleton pattern / static instance.
Had some issues in my code recently surrounding what I now know of as a Circular dependency. In short there are two classes, Player and Ball, which both need to use information from the other. Both at some point in the code will be passed a reference of the other (from another class that will include both .h files).
After reading up on it, I removed the #include.h files from each one and went with forward declaration. This solved the issue of being able to declare the classes in eachother, but I'm now left with an "Incomplete type error" when trying to access a passed reference to the object. There seem to be a few similar examples around, though often mixed with more complex code and hard to narrow down to the basics.
I've rewritten the code in it's simplest form (a skeleton essentially).
Ball.h:
class Player;
class Ball {
public:
Player& PlayerB;
float ballPosX = 800;
private:
};
Player.h:
class Ball;
class Player {
public:
void doSomething(Ball& ball);
private:
};
Player.cpp:
#include "Player.h"
void Player::doSomething(Ball& ball) {
ball.ballPosX += 10; // incomplete type error occurs here.
}
Any help understanding why this is the case would be greatly appreciated :)
If you will place your definitions in this order then the code will be compiled
class Ball;
class Player {
public:
void doSomething(Ball& ball);
private:
};
class Ball {
public:
Player& PlayerB;
float ballPosX = 800;
private:
};
void Player::doSomething(Ball& ball) {
ball.ballPosX += 10; // incomplete type error occurs here.
}
int main()
{
}
The definition of function doSomething requires the complete definition of class Ball because it access its data member.
In your code example module Player.cpp has no access to the definition of class Ball so the compiler issues an error.
Player.cpp require the definition of Ball class. So simply add #include "Ball.h"
Player.cpp:
#include "Player.h"
#include "Ball.h"
void Player::doSomething(Ball& ball) {
ball.ballPosX += 10; // incomplete type error occurs here.
}
Here is what I had and what caused my "incomplete type error":
#include "X.h" // another already declared class
class Big {...} // full declaration of class A
class Small : Big {
Small() {}
Small(X); // line 6
}
//.... all other stuff
What I did in the file "Big.cpp", where I declared the A2's constructor with X as a parameter is..
Big.cpp
Small::Big(X my_x) { // line 9 <--- LOOK at this !
}
I wrote "Small::Big" instead of "Small::Small", what a dumb mistake..
I received the error "incomplete type is now allowed" for the class X all the time (in lines 6 and 9), which made a total confusion..
Anyways, that is where a mistake can happen, and the main reason is that I was tired when I wrote it and I needed 2 hours of exploring and rewriting the code to reveal it.
In my case it was because a typo.
I had something like
struct SomethingStrcut { /* stuff */ };
typedef struct SomethingStruct smth;
Notice how the name of the structure is not the same one as the type definition.
I misspelled struct to strcut.
Look into your code and see wether you have some typos.
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.
This question already has answers here:
"No appropriate default constructor available"--Why is the default constructor even called?
(2 answers)
Closed 7 years ago.
I'm having trouble with a very simple program. It throws the errors:
error C2512: 'Player' : no appropriate default constructor available
IntelliSense: no default constructor exists for class "Player"
I have a feeling it's got something to do with declaring the Player class as a private variable in the Game.h but I can't see why. Any help would be much appreciated.
Game.h
#pragma once
#include "Player.h"
class Game
{
public:
Game(void);
void start(void);
~Game(void);
private:
Player player;
};
Game.cpp
#include "Game.h"
Game::Game(void)
{
Player p(100);
player = p;
}
void Game::start()
{
...
}
Game::~Game(void)
{
}
Player.h
#pragma once
class Player
{
public:
Player(int);
~Player(void);
private:
int wallet;
};
Player.cpp
#include "Player.h"
#include <iostream>
using namespace std;
Player::Player(int walletAmount)
{
wallet = walletAmount;
}
Player::~Player(void)
{
}
In contrast to C#, this declaration;
Player player;
...is an instantiation of the type Player, which means that by the time you're assigning it inside the constructor, it has already been constructed without a parameter.
What you need to do is to tell the class how to initialize player in what is called an initializer list that you append to the constructor header;
Game::Game(void) : player(100)
{
...
...which tells the compiler to use that constructor to initialise player in the first place instead of first using the default no-parameter constructor and then assigning to it.
Only Player::Player(int) exists, so you need to initialize player in Game::Game()
Game::Game(void)
: player( 100 )
{
}
When you construct instance of Game, it tries to construct its member player using the default constructor. Initialize player within the initializer list, not inside the body of constructor:
Game::Game() : player(100)
{
...
}
In general - not in this case - the error
no appropriate default constructor available
may also occur, if you forgot to include the header file for the related object.
This happened to me, so I wanted to add this solution here.
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...