I'm having a little problem trying to use my "gameAux" class in "userAux.hpp" file I made.
Here are the two hpp files I made.
I marked the place where I get an error.
userAux.hpp:
#include "gameAux.hpp"
class userAux{
int gameId;
int userId;
int rate;
gameAux aGame; <---error: ‘gameAux’ does not name a type
};
gameAux.hpp:
#include "userAux.hpp"
class gameAux{
int gameId;
userAux aUser; <--- OK
};
I'll be very happy if someone could point out what's the problem :)
You cannot have one class include an instance of another class, and have that other class include an instance of the first class. That's an infinite recursion and obviously cannot work.
The answer is to use pointers and forward declarations.
class gameAux; // forward declaration
class userAux{
int gameId;
int userId;
int rate;
gameAux* aGame;
};
class gameAux{
int gameId;
userAux* aUser;
};
When two classes depend on each other like this I would be tempted to place them both in the same header file. However if you want separate header files then you could forward declare each class in the other classes header file. That way neither header file needs to include the other.
Your problem is that both of your classes depend on each other. When the compiler goes to see how much space it needs to reserve for gameAux objects, it says 'ok, I need an int and a userAux to fit in there'. So the next question is, how much space does it need for ints and userAux objects?
Then when it tries to figure out how much space it needs for a userAux object, it says 'ok, three ints and a gameAux object'... and there's the problem. It's going to keep going back and forth between those two files, trying to figure out how much space it needs for each thing, and never be able to figure it out.
To solve this, you need to make one of your classes depend on a reference or pointer to the other class. Since references and pointers always take up the same amount of space on a given system, the compiler will be able to allocate space for a userAux if it sees this:
class gameAux;
class userAux{
int gameId;
int userId;
int rate;
gameAux &aGame; // or gameAux *aGame; // <---error: ‘gameAux’ does not name a type
};
and then it will have a fine time allocating space for both of the objects, no problems ^^
EDIT: Also, you won't need to #include the header file for gameAux any more at the top of userAux.hpp - just forward-declare gameAux like so at the top of the file: class gameAux.
You don't need to include the entire class definition. You can avoid a circular dependency by just forward declaring, and using a pointer:
#include "gameAux.hpp"
class gameAux; // forward declaration
class userAux{
int gameId;
int userId;
int rate;
gameAux *aGame;
};
and vice versa in the other file. Then #include the appropriate hpp header in the implementation source file for each class.
Related
I am relatively new to C++, coming from a Python background.
I have the following header file:
struct Example
{
int n_example;
float random_number;
float second_random_number;
Example(int n_example, float random_number, float second_random_number);
};
I do not get what the second to last line do (i.e, Example(int n_example, float random_number, float second_random_number); )
Might be a super silly question, but it is the first time that I encounter such syntax in C++.
Indeed, normally for struct definition I am used to something like:
struct Example
{
int n_example;
float randon_number;
float second_random_number;
};
this here
Example(int n_example, float random_number, float second_randon_number);
is the declaration of the constructor, you can call that and pass the parameters every time you want to construct a new instance of the class Example...
like
int main()
{
Example foo(0, 3.14f, 2.77f);
}
the only thing you are missing is the implementation of that constructor...
it may look like this (depending on what version of c++ you are using):
Example(int n_example, float random_number, float second_random_number) :
n_example{n_example},
random_number{random_number},
second_random_number{second_random_number},
{
...
}
The line you're questioning is a class constructor and as far as I'm aware is something equivalent to __init__ in Python. The reason it's declared in the class definition body - between {} - is because C++ is strongly typed, which means that the class definitions has to be fully specified. You cannot "add" new functionality afterwards, during a runtime of a program. Contrary to C++, Python belongs to loosely typed group of languages where you can define classes' fields and methods on the go during a runtime which makes it more flexible but more error-prone in the end.
Also be aware that this is just a simple declaration which should be included within the header file .h The definition of this constructor most of the time (unless inlined) will end up in respective .cpp file which consist of all the logic related to the class. This separation of declaration .h and definition .cpp files is one of the building blocks of the language. In the end only the .cpp files are compiled and then linked together resulting in a hopefully working application.
(it is be possible that this question has been asked very often already and i am sorry about this repost, but anything i found just didnt help me, since i am relatively a beginner at c++)
so here is an example to show my problem
i have the class monster
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and i have the class Level
class Level{
Level();
};
i have created the object "snake" from the class Monster in my "main.cpp"
#include "Monster.h"
int main(){
Monster snake;
}
now what do i do if i want to use "snake" in my "Level" class? if i want to do "snake.attack();" inside of "Level.cpp" for example?
If i declare it again in "Level.cpp" it will be a seperate object with its own attributes wont it?
i have always been making the member functions of my classes static until now, so i could do "Monster::attack();" anywhere in my program but with this tachnique i cant have multiple objects doing different things depending on their attributes (snake1, snake2, bat1, etc...)
thanks for the help in advance!
(and sorry for the possibly reoccuring question)
Presuming those snips are your .h files.
Your level.cpp should something like this:
#include "level.h" // its own header
#include "monster.h" // header with Monster::attack() declaration
Level::DoAttack(Monster& monster) { // using snake as parameter.
health = health - monster.attack(); // monster hits us, subtract health.
}
monster.h would be
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and monster.cpp
Monster::attack() {
// code to calculate the attack
}
I could not completely understand your questions.But from what I understood.I think you want to access a Monster object instantiated in main() to be used inside level.So,here is what you can do.Add a constructor inside the level class which takes a monster object as an argument.Then instantiate a level object and pass the monster object in it.Like this,
Level l=new Level(snake);
By declaring a class you're not creating any objects. You normally declare a class by including the corresponding header file.
So, in Level.h you'd #include <Monster.h>, then you can reference it inside Level.
But seriously, you can't write much C++ code without understanding the basic things such as declaration vs. definition, header files (.h), classes vs. objects, pointers and references, etc. It would be best to invest in a book or at least to read some tutorials online.
I'm trying to make class functions I can tack on to other classes, like with nested classes. I'm still fairly new to C++, so I may not actually be trying to use nested classes, but to the best of my knowledge that's where I'm at.
Now, I've just written this in Chrome, so it has no real use, but I wanted to keep the code short.
I'm compiling on Windows 7, using Visual Studio 2015.
I have two classes in file_1.h:
#pragma once
#include "file_2.h"
class magic_beans{
public:
magic_beans();
~magic_beans();
int getTotal();
private:
double total[2]; //they have magic fractions
}
class magic_box{
public:
magic_box(); //initiate
~magic_box(); //make sure all objects have been executed
void update();
magic_beans beans; //works fine
magic_apples apples; //does not work
private:
int true_rand; //because it's magic
};
... And I have one class in file_2.h:
#pragma once
#include "file_1.h"
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}
Now, I've found that I can simply change:
magic_apples apples;
To:
class magic_apples *apples;
And in my constructor I add:
apples = new magic_apples;
And in my destructor, before you ask:
delete apples;
Why must I refer to a class defined in an external file using pointers, whereas one locally defined is fine?
Ideally I would like to be able to define magic_apples the same way I can define magic_beans. I'm not against using pointers but to keep my code fairly uniform I'm interested in finding an alternative definition method.
I have tried a few alternative defines of magic_apples within my magic_box class in file_1.h but I have been unable to get anything else to work.
You have a circular dependency, file_1.h depends on file_2.h which depends on file_1.h etc. No amount of header include guards or pragmas can solve that problem.
There are two ways of solving the problem, and one way is by using forward declarations and pointers. Pointers solve it because using a pointer you don't need a complete type.
The other way to solve it is to break the circular dependency. By looking at your structures that you show, it seems magic_apples doesn't need the magic_beans type, so you can break the circle by simply not includeing file_1.h. So file_2.h should look like
#pragma once
// Note no include file here!
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Cross referencing included headers in c++ program
(5 answers)
Closed 9 years ago.
For example a little Computergame with three Classes Player, Bot and Game
Player has a Method that checks if the Player collide with a bot
// Player.h
#include Game.h
#include Bot.h
class Player {
private:
bool collision(Game g) {
for (Bot bot: g.bots)
...
}
};
The Bot.h (kept simple, of cause it has some other attributes like actual position and so far)
// Bot.h
class Bot {
public:
Bot()
};
The Gameclass handles the Gameloop and the List of Bots
//Game.h
#include Bot.h
#include Player.h
class Game {
public:
Player player:
std::vector<Bot> bots
void loop() { player.collision() }
};
So here we have the problem that Game.h includes Player.h and the other way around.
How can I resolve this?
While the other answers here are certainly technically correct, whenever I come across a situation like this I see it as pointing out a potential flaw in my design. What you have is cyclic dependencies, like so:
This isn't just a problem for your implementation, it means that there is too much coupling between classes, or, conversely, too little information hiding. This means that you can't design the Player independently of the Game, for example.
So if possible, I'd prefer a situation like this, where the Game, as the controller delegates work out to other classes.
One way to do this is for the Game to pass references to its own properties as and when the Player needs them.
For example have collision take a bots parameter rather than the `Game
bool collision(const std::vector<Bot&> bots) {
// note pass objects by const ref is usu preferred in C++ to pass by value
for (Bot bot: g.bots)
...
}
(Note in a more sophisticated approach, it could pass interfaces, i.e. abstract base classes, onto itself).
If all else fails, you can go back to using a forward declaration.
In this case the easiest thing would be a forward declaration, and moving some code from the header file to the source file.
Like this
Player.h
#include "Bot.h"
class Game; // forward declaration
class Player {
private:
bool collision(Game g);
};
Player.cpp
#include "Player.h"
#include "Game.h"
bool Player::collision(Game g) {
for (Bot bot: g.bots)
...
}
The forward declaration tells the compiler that Game is the name of a class but nothing else. So the Player::collision method must be moved to the Player.cpp file where the full definition of Game is available.
I dont think you can do this since If A contains B, and B contains A, it would be infinite size. Infact you can create two classes that store pointers to one another, by using the forward declaration, so that the two classes know of each other's existence
Forward declaration is required - http://en.wikipedia.org/wiki/Forward_declaration
So I am trying to define a class and I am using another array of a different class to define it.
//header file for Name.h
class Name {
string last;
string first;
};
//header file for Depositor.h
class Depositor {
Name name;
string ssn;};
//header file for Account.h
class Account {
Depositor depositor;
int acctnum;
string type;
double balance;
};
//header file for Bank.h
#include "Account.h"
class Bank {
Account account[]; //is this possible?
int active_accts;
};
When I am writing the cpp file I am running into a lot of problems!
//example of mutator
void Bank::setLastname(string lastname)
{
account.setLastname (lastname);
}
I didn't include the mutators and acessors that I wrote into the header file, but they are there and are public -- it won't compile.
Can you help? Is it even valid to use an array of a class in Bank.h?
Is it even valid to use an array of a class in Bank.h?
Yes, but it has to have a fixed dimension, e.g.,
Account account[3];
A type always has a fixed size in C++, and since an array member variable forms part of the class's size, you need to specify how many elements are in the array.
If you don't know how many elements you are going to need, you can use a sequence container:
std::vector<Account> account;
Account is not a nested class of Bank. Bank has a member data instance of type Account array.
You can have a primitive array member in a class, but you must specify the size of the array in the class definition: Account account[42];. The reason is that when you #include the class definition in another compilation unit, and then instantiate an instance of the class, the compiler needs to know what the size of that instance is.
It would be a wise idea to use std::vector<Account> rather than a primitive array. std::vector doesn't require committing to a particular size at construction; it grows dynamically. How come a std::vector doesn't require a size in the class definition, while a primitive array does? A std::vector holds as member a pointer to the elements on the heap. So the compiler does know the size of a std::vector; it uses the size of the pointer rather than the count of the elements.
By declaring the value of the array in the header file and by adding a variable in the .cpp file you can solve all the problems and leave it as an array.
//header file
class Bank {
Account account[100];
int active_accts;
public:
//mutator
void setLastname (string,int);
};
//the implementation file
void Bank::setLastname (string last, int index)
{
account[index].setLastname(last);
}
this will solve all your problems
account is an array of Accounts, which means you would need to do something like account[0].setLastname(lastname);
Instead of arrays, consider using vectors.
#include <vector>
// ...
class Bank {
std::vector<Account> accounts;
int active_accts;
};
you can't call setLastname(lastname) on the whole array. You need to call it on a specific instance of the Account class inside the array, like this: account[0].setLastname(lastname);
On another note, you really should be storing an array of pointers to Account objects.