How to make classes in NACHOS (C++) - c++

I am trying to implement a player class, so I created two files in my threads folder,
player.cc and player.h
player.h goes like this :
#ifndef PLAYER_H
#define PLAYER_H
#include "utility.h"
class Player()
{
public:
//getPlayerID();
};
#endif
then player.cc goes like
#include "player.h"
class Player()
{
string playerID;
int timeCycle;
}
Then in my main.cc and threadtest.cc , I add in #include player.h and then I start to errors and it fails to compile. I am new to nachos and a little bit unfamiliar with c++, so I am confused as to how to resolve this problem. Nachos does not provide a solution through the compiler either.
When I type gmake, it says two things for errors.
1. parse error before '(' in player.h (referring to Player())
2. * [main.o] Error 1

Let's go through line-by-line:
#ifndef PLAYER_H
#define PLAYER_H
#include "utility.h"
So far so good, you might check if your compiler supports #pragma once, but the macro will work perfectly fine.
class Player()
() aren't allowed in a class name, take them off
{
public:
//getPlayerID();
};
#endif
The rest of the header file is ok. Let's look at the implementation file:
#include "player.h"
Perfect. Putting a class in a header is the best way to make sure you only have one definition used in your whole program.
class Player()
Parentheses aren't allowed, but here you have a bigger problem. You already have a class with that name. Let the header provide the class definition, the implementation file just needs to provide the non-inline member functions (and any helper code).
{
string playerID;
int timeCycle;
}
Here's a complete corrected version:
#if !defined(PLAYER_H)
#define PLAYER_H
#include <string>
#include "utility.h"
class Player
{
std::string player_id;
int time_cycle;
public:
// this is how you make a constructor, the parenthesis belong here, not on the class name
Player(std::string id, int time);
std::string getPlayerId() const;
};
#endif /* !defined(PLAYER_H) */
and implementation file
#include "player.h"
// and this is how you write a non-inline constructor
Player::Player(std::string id, int time)
: player_id(id)
, time_cycle(time)
{}
std::string Player::getPlayerId() const
{
return player_id;
}
All of these problems are really basic C++ stuff, nothing to do with NachOS.

Did you modify the Makefile.common in the root nachos directory? I think you should add some value to THREAD_H, THREAD_O and THREAD_C.

Related

Swarmed with identifier errors

I've been programming a Monopoly game for a final project. So I thought I was on a roll, and that I had everything figured out with my psuedocode. But, it seems I forgot how to deal with includes properly, I know that is the issue since I was able to refine it to that point, but I'm not sure how to fix it.
In this super stripped down version of my code I have three .h files "Space.h" which is an abstract/virtual class which has to be inherited by a variety of different spaces that can appear on a typical Monopoly board: properties, jail, taxes, Chance, Community Chest, etc. The function that has to be inherited is run(Player&) which is what is "run" when you land on that particular space on the board, all functions that use run use a player passed by argument.
#pragma once
#include <string>
#include "Player.h"
class Space
{
public:
virtual void run(Player&) = 0;
};
My second .h file is the "Property.h" this inherits from Space
#pragma once
#include "Space.h"
class Property : Space
{
public:
void run(Player&) override;
int i{ 0 };
};
Lastly I have the "Player.h" which has two variables a name and a vector of properties it owns.
#pragma once
#include <string>
#include <vector>
#include "Property.h"
class Player
{
public:
std::string name{ "foo" };
void addProperty(Property p);
private:
std::vector <Property> ownedProperties;
};
Here's a very basic Property implementation
#include "Property.h"
#include <iostream>
void Property::run(Player & p)
{
std::cout << p.name;
}
Player implementation
#include "Player.h"
#include <iostream>
void Player::addProperty(Property p)
{
ownedProperties.push_back(p);
}
And finally main
#include "Player.h"
#include "Space.h"
#include "Property.h"
int main()
{
Player p{};
Property prop{};
prop.run(p);
system("pause");
}
Every time this is run I get a slew of errors, I'm sure it's got to do something with the circular include logic, with player including property, and property including space, which includes player. But, I don't see a workaround considering #include is needed to know how everything is defined isn't? Or are these errors referring to something else?
You have a circular include problem. Player includes Property which includes Space which includes Player again.
You can break the circle by not including Player.h in Space.h and only forward declare the class
#pragma once
class Player;
class Space
{
public:
virtual void run(Player&) = 0;
};

C++ Why Is There "Unknown Type" When Class Header is Included? [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 6 years ago.
I have this header file and I'm trying to make variables of type Item. I've included #include "Item.h" and yet I still get a unknown type name Item error on both private variables when I compile.
#ifndef PLAYER_H
#define PLAYER_H
#include <vector>
#include "Item.h"
using std::vector;
class Player
{
public:
// constructor
Player( void );
// destructor
virtual ~Player( void );
private:
Item item;
std::vector <Item> inventory;
};
#endif /* PLAYER_H */
Whats up with this?
Heres the Item.h that I'm including
#ifndef ITEM_H
#define ITEM_H
#include <string>
#include "Player.h"
#include "GlobalDefs.h"
class Item {
public:
Item();
Item(gold_t v, std::string n);
virtual ~Item();
// Getter
inline virtual gold_t GetValue (void)
{
return value;
}
// Getter
inline virtual std::string GetName (void);
// Getter
virtual std::string GetItemText(void);
protected:
gold_t value;
std::string name;
};
#endif /* ITEM_H */
If you include Item.h from your cpp file, Player.h is included from it. Then, Player.h includes Item.h again, but thanks to the include guard, this does virtually nothing.
Then, in the included Player.h, no Item is declared yet. Therefore, the compiler will emit the error.
Since nothing from Player.h is used in Item.h, remove #include "Player.h" from Item.h.
You're including "Player.h" in "Item.h" and make it circular dependency. Since it's not necessary at all so just remove it.

C++: Inclusion inside inclusion

The title might not be very clear, it's a bit more complex than that. I searched the web for something like my problem but I did not find anything that could help me.
This is not about infinite looping inclusions, I already put preprocessor directives to avoid that.
I have two classes Monster and Character, respectively declared in their own header files, monster.hpp and character.hpp, and respectively implemented in their own source files, monster.cpp and character.cpp.
The problem now is that both classes need each other to work.
monster.hpp :
#ifndef INCLUDE_MONSTER_HPP
#define INCLUDE_MONSTER_HPP
#include "character.hpp"
class Monster
{
private: //Atributes
public: //Methods
void attackM(Monster& id);
void attackC(Character& id);
};
#endif //MONSTER_HPP_INCLUDED
character.hpp :
#ifndef INCLUDE_CHARACTER_HPP
#define INCLUDE_CHARACTER_HPP
#include "monster.hpp"
class Character
{
private: //Attributes
public: //Methods
void attackM(Monster& id);
void attackC(Character& id);
};
#endif //CHARACTER_HPP_INCLUDED
and the main.cpp :
#include <iostream>
#include "character.hpp"
#include "monster.hpp"
using namespace std;
int main(int argc, char **argv)
{
//Whatever
return 0;
}
And I get this error from the compiler :
In file included from character.hpp:7:0,
from main.cpp:3:
monster.hpp:24:16: error: 'Character' has not been declared
void attackC(Character& id);
(the line and column numbers may be wrong)
From what I understand, when monster.hpp is included into character.hpp, the compiler sees that the class Monster uses the class Character, which is not declared yet right at the moment when monster.hpp is included into character.hpp.
And I don't know how to fix that.
Any ideas ?
The way this works is that the header files of char and monster do not include each other. Instead you forward declare the classes and include the headers within the CPP files.
So basically replace #include "monster.hpp" in the.h with class Monster; and #include "monster.hpp" in the .cpp - and same for the other class.
See this question for more details:
What are forward declarations in C++?
#ifndef INCLUDE_MONSTER_HPP
#define INCLUDE_MONSTER_HPP
#include "character.hpp"
class Character;
class Monster
{
private: //Atributes
public: //Methods
void attackM(Monster& id);
void attackC(Character& id);
};
#endif //MONSTER_HPP_INCLUDED
You need to use a forward declaration. See: http://en.wikipedia.org/wiki/Forward_declaration
Basically, the compiler doesn't know what a "Character" is. You temporarily indicate that it's something you can point to by adding the following stub to Character.hpp:
class Character;
Use predeclaration in *.h:
class Character;
class Monster;
use in *cpp the includes:
#include "character.h"
#include "monster.h"
Or put everything in one *.hpp with predeclaration.

C++ include files confusion

I'm trying to include files in my c++ program but I keep encountering the error:
ShapeVisitor.h:9:28: error: ‘Circle’ has not been declared
I think the problem is that the way the classes are structured, it results in a circular dependence. How do I solve this?
The class headers are below...
//Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
// headers, ...
#include "Shape.h"
class Circle: public Shape {
//class declaration
}
#endif
//Shape.h
#ifndef SHAPE_H
#define SHAPE_H
// headers, ...
#include <iostream>
class Shape {
//a certain method in the class declaration looks like this
virtual void accept(ShapeVisitor& v) = 0;
//rest of class
}
#endif
//ShapeVisitor.h
#ifndef SHAPEVISITOR_H
#define SHAPEVISITOR_H
#include "Circle.h"
class ShapeVisitor {
//a method in the class looks like this:
virtual void visitCircle(Circle *s) = 0;
//rest of class
}
#endif
As you can see, circle includes shape, which includes shapevisitor, which again, includes circle.
Any ideas?
ShapeVisitor.h does not need to include Circle.h, a forward declaration class Circle; will do. Function declarations do not require the full definitions of their argument and return types (not even if the return/arguments are by value!). Only the function's implementation file (in your case: ShapeVisitor.cpp) would need to include Circle.h.
This ancient (but still very true!) column by Herb Sutter is a nice reference.

inheritance error: "expected class-name before '{' token"

I am writing a poker program, where two classes I have are a Deck class and a Hand class. The Hand class inherits from the Deck class, so it can use its printGroup method. However, when I compile I get an error that says:
expected class-name before '{' token
referring to the line:
class Hand : public Deck{
Here is the code for the two class headers. Could anyone help me solve this?
//Hand header
#ifndef HAND_H
#define HAND_H
#include <iostream>
#include <vector>
#include "Deck.h"
#include "Card.h"
class Card;
class Hand : public Deck{ //error occurs from this line
public:
Hand(){}
void createHand(std::vector<Card> &, std::vector<Card> &);
};
#endif /* HAND_H */
//Deck header
#ifndef DECK_H
#define DECK_H
#include <iostream>
#include <vector>
#include "Card.h"
class Card;
class Deck{
public:
Deck(){}
void createDeck(std::vector<Card> &);
void printGroup(std::vector<Card> &, int);
void sortDeck(std::vector<Card> &, int, int);
};
#endif /* DECK_H */
Assuming that #marcog's gut feeling that it is a circular dependency is correct (maybe Card.h includes Hand.h, thereby importing the file Hand.h before getting up to the declaration of the Deck class), this can be solved by forward declarations.
I see you already have a forward declaration of the Card class ("class Card;"). Therefore, do you really need to #include "Card.h"? If you remove that include, you can still refer to the class Card due to the forward declaration, but it may resolve the cyclic dependency.
I usually don't #include .h files from other .h files in C++ unless I really have to. If you are just referring to a class in another file (by pointer, reference, or putting it in a container like vector), then you can get away with just forward-declaring the class, and physically including the header file from the .cpp file only.