I've read tons of similar questions,but I still can not figure it out. Error I get in QT creator when I try to compile this is next: "Grid has not been declared",although I included the Grid class header in the bunny class which displays this error. Here are my codes:
(Error is produced in function line "void becomeVampire(Bunny *& , int &,Grid &);" ,which is fifth if you count from down to up, in first(BUNNY) class, and also in function "void convertNeighbourToVampire(Bunny * const, int &, Grid &);" which is first from down to up: Both of these functions use reference to Grid class as one of parameters)
#ifndef BUNNY_H
#define BUNNY_H
#include <conio.h>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <time.h>
#include <windows.h>
#include "Position.h"
#include "Grid.h"
int GetRandom(int x);
class Bunny:public Position
{
private:
static const std::vector <std::string> F_names; //all the female names
static const std::vector <std::string> M_names; //all the male names
static const std::vector <std::string> colors; //all the colors
bool isMale= GetRandom(2)<1 ? true : false; //at creation,bunnies gender is randomly chose//50%chance
bool isVampire= GetRandom(100)< 2 ? true : false; //2% chance for birth of vamp bunny
std::string name;
std::string color;
std::string sex;
std::string vampire;
int age;
void Inner(int & TVamps); //use this inside of constructors,assign all needed info to a bunny
void half(Bunny *&,int &); //halfs the population randomly
void increaseAge(); //called by ageUp() function,increases the age of a particular bunny object
public:
Bunny * Next; //pointer to next bunny in linked list
Bunny(int & TVamps); //DEFAULT CONSTRUCTOR
Bunny(std::string C,int & TVamps); //CHILDREN CONSTRUCTOR
~Bunny(); //DESTRUCTOR
//NEXT is self explanatory
bool isMatureMale() const {if( (this->age>2) &&(isMale) &&(!isVampire) ){return true;} return false;}
bool isMatureFemale() const {if( (age>2) &&( !isMale) &&(!isVampire) ){return true;} return false;}
bool getIsMale() const {return isMale;}
std::string getName() const {return name;}
std::string getColor() const {return color;}
std::string getSex()const {return sex;}
std::string getVampire() const{return vampire;}
bool getIsVampire() const {return isVampire;}
int getAge() const {return age;}
void makeVampire(int &); //make certain bunny a vampire
bool isEmpty(Bunny *) const; //is bunny colony empty
void ageUp(Bunny *); //increase the populations age by 1
void insertBunny(Bunny *,Bunny *&, int &,int &); //add a child,parameters are: head pointer,reference of last pointer,and counter of bunnies and vampires
void insertFirstBunny(Bunny *&, int &,int &); //insert a bunny with no parrent
void printBunnies(Bunny * , int , int,int) const; //prints out the whole colony info
void removeBunny(Bunny *& ,int &, int &); //removes old bunnies
**void becomeVampire(Bunny *& , int &,Grid &); //converts bunnies to vampires**
void FoodShortage(Bunny *& ,int &); //kills half of bunnies randomly,takes pointer reference of head pointer as parameter
void massRabitKull(Bunny *&,int &); //when "k" or "K" is pressed,calls the half() function
bool isArrayOutOfBounds(int x, Bunny const * const temp); // north-1 south-2 east-3 west-4
void convertNeighbourToVampire(Bunny * const, int &, Grid &);
};
#endif // BUNNY_H
And here is the Grid class:
#ifndef GRID_H
#define GRID_H
#include "Position.h"
#include "Bunny.h"
class Grid
{
private:
char GridField[80][80];
void renewGrid(); //sets all grid positions to '.',called by constructor and updateTheGrid()
public:
Grid();
void updateTheGrid(Bunny * const); //sets all grid positions to new positions based on new bunny objects linked list
void printTheGrid() const; //prints the grid to the new file
char getGridField(int,int); //returns the character on certain position
};
#endif // GRID_H
and the last class, Position:
#define POSITION_H
#include "Grid.h"
class Position
{
private:
int row,column;
char sign;
public:
Position();
Position ( int parrentRow,int parrentColumn );
int getRow() const ;
int getColumn() const;
char getSign() const;
};
#endif // POSITION_H
Related
I am writing a small program, for a school project, that emulate a shared editor (like Google Docs)
I've written all the classes that I need but when I try to build the program I get this errors:
error: unknown type name 'NetworkServer'
NetworkServer &_server;
error: use of undeclared identifier 'SharedEditor' std::vector<SharedEditor*> SEditors;
error: expected expression std::vector<SharedEditor*> SEditors;
error: unknown type name 'SharedEditor' int connect(SharedEditor* sharedEditor);
Here are my .h files
NetworkServer.h
#include <vector>
#include <queue>
#include "SharedEditor.h"
#include "Message.h"
class NetworkServer {
private:
std::vector<SharedEditor*> SEditors;
std::vector<int> idEditors;
std::queue<Message> messages;
public:
int connect(SharedEditor* sharedEditor);
int disconnect(SharedEditor* sharedEditor);
void send(const Message& m);
void dispatchMessages();
};
SharedEditor.h
#include "NetworkServer.h"
#include "Message.h"
#include "Symbol.h"
class SharedEditor {
private:
NetworkServer& _server;
int _siteId{};
std::vector<Symbol> _symbols;
int _counter;
public:
SharedEditor() = delete;
SharedEditor(NetworkServer& server);
void localInsert(int index, char value);
void localErase(int index);
void process(const Message& m);
std::string to_string();
int getSiteId() const;
};
Symbol.h
#include <vector>
class Symbol {
private:
char value;
int idClient;
int num;
std::vector<int> pos;
public:
Symbol(char value, int client, int num, std::vector<int> pos);
char getValue() const;
int getIdClient() const;
int getNum() const;
const std::vector<int> &getPos() const;
};
Message.h
#include <vector>
class Message {
bool insert; // true --> insert || false --> delete
int _siteId;
int num;
char value{};
std::vector<int> pos;
public:
Message(bool insert, int siteId, int num, char value, std::vector<int> pos);
Message(bool insert, int siteId, int num);
bool isInsert() const;
int getSiteId() const;
int getNum() const;
char getValue() const;
const std::vector<int> &getPos() const;
};
I don't understand where I am doing something wrong. BTW I am using CLion
So I'm getting this error "Female is not a type" when compiling, even tho I've tried forward declaring the class Female in the following code:
Male.hpp :
#ifndef GUARD_MALE_HPP
#define GUARD_MALE_HPP
#include <Elephant_Base.hpp>
#include <SFML/System/Time.hpp>
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <TextureHolder.hpp>
#include <memory>
#include <Female.hpp>
//class Female; --> doesn't work
class Male : public Elephant_Base {
public:
Male();
Male(Traits traits);
Male(TextureHolder& text, bool hasTusks, age_value a = 0);
void update(sf::Time dt);
void tryToMate(Female& f); //<--- shows error here
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
};
#endif
Female.hpp :
#ifndef GUARD_FEMALE_HPP
#define GUARD_FEMALE_HPP
#include <Elephant_Base.hpp>
#include <SFML/System/Time.hpp>
#include <TextureHolder.hpp>
#include <memory>
class Female : public Elephant_Base {
public:
Female();
Female(Traits traits);
Female(TextureHolder& text, bool hasTusks, age_value a = 0);
void update(sf::Time dt);
//female methods
bool canGetPregnant() const;
bool hasChildGrown() const;
Elephant_Base::Ptr detachChild();
bool isPregnant() const;
private:
//female functions
void drawChild(sf::RenderTarget& target, sf::RenderStates states) const;
void makePregnant(const Elephant_Base::Gene& maleGamete);
void giveBirth(); //called in update; will create a child
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
private:
//female members
Elephant_Base::Ptr mChild;
bool mIsPregnant;
age_value mGestationTime;
};
#endif
I've also tried without forward declaration, I still get the same error, so I'm kinda lost about what should be done here...
EDIT: file Elephant_Base.hpp has been asked, here it is:
#ifndef GUARD_ELEPHANT_BASE_HPP
#define GUARD_ELEPHANT_BASE_HPP
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/Transformable.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/System/Time.hpp>
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include "TextureHolder.hpp"
#include <memory>
class Elephant_Base : public sf::Drawable, public sf::Transformable {
public:
typedef float age_value;
typedef std::shared_ptr<Elephant_Base> Ptr;
const static sf::Time YEAR_IN_SECONDS_VALUE; //represents the value of a year in a certain amount of seconds
//enum to define if the Elephant is going to be male or female hence determining the sexual chromosomes
enum Sex {
Male,
Female,
None,
};
//it's actually the sexual chromosomes, but this app aims to study the gene that grows tusks on the elephants
//Xi is dominant and is the gene that grows tusks
enum Gene {
Xi,
Xi_,
Y,
Undefined,
};
struct Traits {
Traits();
Traits(TextureHolder& text, Sex s, bool hasTusks, age_value a = 0);
Traits(TextureHolder& text, std::pair<Gene, Gene> g, age_value a = 0);
Sex sex;
std::pair<Gene, Gene> genes;
bool tusks, alive;
age_value age;
TextureHolder* textures;
static bool hasTusks(std::pair<Gene, Gene> g);
private:
//generates random pair of Gene depending on the elephant's sex and tusks
void generateGenes(Sex sex, bool hasTusks);
//generate random pair of genes depending on sex
void generateRandomGenes(Sex sex);
};
public:
Elephant_Base();
Elephant_Base(Traits traits);
Elephant_Base(TextureHolder& text, Elephant_Base::Sex sex, bool hasTusks, age_value a = 0);
virtual ~Elephant_Base();
//general methods
virtual void update(sf::Time dt) = 0;
void setEnclosure(sf::IntRect limits); //sets a limit range in which the Elephant can move
void kill();
bool hasTusks() const; //returns true if mTraits.tusks = true, hence Elephant has tusks
bool isAlive() const;
sf::FloatRect getBoundaries() const;
Traits getTraits() const;//returns mTraits
static Gene randomGeneX(); //returns either Gene::Xi or Gene::Xi_ with equal chances for both
protected:
//general functions
void toAge(sf::Time dt);
Gene generateGametes() const; //generates a random Gene amongst owned ones
void updateMovement(sf::Time dt);
protected:
sf::Sprite mShape;
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
private:
//general members
Traits mTraits;
sf::Vector2f mMovement;
sf::IntRect mEnclosure;
};
#endif
EDIT 2: Some people pointed that Female may have been declared before and indeed I already have a Sex::Female in an enum. So I have to change the name of one of the both.
This question already has answers here:
Why does C++ allow us to surround the variable name in parentheses when declaring a variable?
(2 answers)
Closed 5 years ago.
Hello,
I'm trying to instantiate an anonymous object with a std::string variable 'name'. But intellisenen gives me error saying
E0291 no default constructor exists for class "Player" GoldGame e:\C++ Projects\Hello World\GoldGame\GoldGame.cpp 17
I have provided a constructor which can just take a std::string variable since other parameters are provided with default value.
Can you guys shed some light on this?
What confuses me even more is that when I change
Player(name);
to
Player a(name);
or to
Player("test");
then intellisense becomes totally fine with those.
GoldGame.cpp
#include "stdafx.h"
#include "Creature.h"
#include "Player.h"
#include <iostream>
#include <string>
int main()
{
std::cout << "Enter your name: ";
std::string name;
std::cin >> name;
Player(name);
return 0;
}
Creature.h
#pragma once
#include <string>
class Creature
{
public:
Creature(const std::string &name, const char symbol, const int health, const int damage, const int gold);
~Creature();
//getters
const std::string& getName() { return m_name; }
const char getSymbol() { return m_symbol; }
const int getHealth() { return m_health; }
const int getDamage() { return m_damage; }
const int getGold() { return m_gold; }
//health, gold and dead
void reduceHealth(const int healthMinus);
void addGold(const int gold);
bool isDead();
private:
std::string m_name;
char m_symbol;
int m_health;
int m_damage;
int m_gold;
};
Creature.cpp
#include "stdafx.h"
#include "Creature.h"
Creature::Creature(const std::string & name, const char symbol, const int health, const int damage, const int gold)
:m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
{
}
Creature::~Creature()
{
}
void Creature::reduceHealth(const int healthMinus)
{
m_health -= healthMinus;
}
void Creature::addGold(const int gold)
{
m_gold += gold;
}
bool Creature::isDead()
{
if (m_health>0)
{
return true;
}
else
{
return false;
}
}
Player.h
#pragma once
#include "Creature.h"
#include <string>
class Player :
public Creature
{
public:
Player(const std::string &name, const char symbol='#', const int health=10, const int damage=1, const int gold=0);
~Player();
const int getLevel() { return m_level; }
void levelUp();
bool hasWon();
private:
int m_level;
};
Player.cpp
#include "stdafx.h"
#include "Player.h"
Player::Player(const std::string & name, const char symbol, const int health, const int damage, const int gold)
:Creature(name,symbol,health,damage,gold)
{
}
Player::~Player()
{
}
void Player::levelUp()
{
++m_level;
}
bool Player::hasWon()
{
if (m_level>=20)
{
return true;
}
else
{
return false;
}
}
Player(name); does not do what you think it does. It declares a new variable name of type Player and calls a default constructor. If you want to instantiate an anonymous Player variable then you need to write
(Player(name));
// or
Player{name}; // list initialization since C++11
I'm getting this error, and I don't know why. I got part of the code from Mark Allen Weiss' book. He makes his hashEntry struct the exact same way (I used different names though). Am I doing something wrong using enum or forgetting to include something?
#ifndef QHASHTABLE
#define QHASHTABLE
#include <iostream>
#include <vector>
#include "functions.h"
using namespace std;
class quadraticHashTable
{
public:
explicit quadraticHashTable(int size = 101)
: hashArray(nextPrime(size)), currentSize{0}
{ makeEmpty(); };
bool contains(const int & searchItem);
void makeEmpty();
bool insert(const int & insertItem);
bool remove(const int & removeItem);
int getCurrentSize();
void testDisplay() const;
enum EntryType { ACTIVE, EMPTY, DELETED }; //ACTIVE = 0, EMPTY = 1, DELETED = 2
private:
struct hashEntry
{
int value;
EntryType status;
hashEntry(const int & v = int{}, EntryType s = EMPTY) //ERROR HERE
: value( v ), status( s ){}
};
size_t hashFunction(int value);
bool isActive(int currentPos) const;
int findPos(const int & value);
void reHash();
void reHashDelete();
vector<hashEntry> hashArray;
int currentSize;
};
I'm having a problem with #including files in C++. When I try to compile the following code
#ifndef TILE_H_INCLUDED
#define TILE_H_INCLUDED
#include "location.h"
#include "Thing.h"
#include "Container.h"
#include <string>
using namespace std;
class Tile //VIRTUAL CLASS
{
protected:
Container onTile; //holds objects that are on the tile
Location * loc; //location
Tile* N; //links to Tiles of that direction (null if nothing)
Tile* E;
Tile* S;
Tile* W;
public:
//no constructor because superclass?
//loc can't move
//actions
bool placeOnTile(Thing * i){return onTile.addItem(i);}
//put a thing on the tile (on the floor)
Thing* takeFrmTile(int i){return onTile.movItem(i);}
//take a thing from the tile (from the floor)
Thing* access(int i) {return onTile.getItem(i);}
//gets an item, but doesn't move it (for like, flipping switches)
//direction setters/getters
void setLoc(Location* i){loc = i;}
void setN(Tile* i){N = i;}
void setE(Tile* i){E = i;}
void setS(Tile* i){S = i;}
void setW(Tile* i){W = i;}
Location* getLoc(){return loc;}
Tile* getN(){return N;}
Tile* getE(){return E;}
Tile* getS(){return S;}
Tile* getW(){return W;}
//displays
void dispOnTile(){onTile.allDisplay();}
void dispSingle(int i){onTile.singleDisplay(i);}
};
I get the error message that "Container" and "Thing" are not defined. Why is this? The #includes look to me like they are coded correctly, and they've worked in the past. I assumed it might be an issue of the #included files being not end-bracketed correctly or not using the same namespace, but they are ended correctly (with a }; ) and they are using the standard namespace. What's up? I can't find an answer and I know it's got to be something simple. For the record, the #included files are below:
#ifndef CONTAINER_H_INCLUDED
#define CONTAINER_H_INCLUDED
#include "Thing.h"
using namespace std;
class Container
{
private:
Thing ** contents; //array of pointers to Things
int numItems; //count item
int maxSize; //maxSize
public:
//constructor
Container(int i) {contents = new Thing*[i]; numItems = 0; maxSize=i;}
//sets num of items (for set-size bags)
Container() {contents = new Thing*[100]; numItems = 0; maxSize=100;}
//creates array of things
~Container() {delete contents;} //cleanup
//actions
bool addItem(Thing* th); //adds item to bag (really just rereferences the pointer)
bool rmvItem(int i); //removes item in array pos i
Thing* getItem(int i); //returns a pointer to item at array pos i
Thing* movItem(int i); //moves an item (deletes it and returns it)
//construction tools
void setMax(int i){delete contents; contents = new Thing*[i];}
//displays
void allDisplay(); //displays entire contents of container, numerated
void singleDisplay(int i); //displays content item i
};
#endif // CONTAINER_H_INCLUDED
#ifndef LOCATION_H_INCLUDED
#define LOCATION_H_INCLUDED
#include <string>
#include <sstream>
#include "Tile.h"
using namespace std;
class Location //stores xy coordinates of something
{
int x; //0 is NOT on map
int y;
Tile* ti; //Locations contain pointers to tiles
public:
//constructors (mainly for debug)
Location(){x=y=0;} //put object OUT OF MAP
Location(int ix, int iy){x=ix;y=iy;} //put object AT loc on map
//setters
void setX(int ix){x=ix;} //sets x
void setY(int iy){y=iy;} //sets y
void setT(Tile*i){ti=i;} //sets Tile
//getters
int getX() {return x;}
int getY() {return y;}
string getloc() //return location as a string, separated by a comma
{
ostringstream locxy; //create stringstream obj to handle input
locxy << getX() << "," << getY() << ". "; //put x, space, y into stringstream
string locret = locxy.str(); //convert stringstream to string
return locret; //return string
}
};
#endif // LOCATION_H_INCLUDED
#ifndef THING_H_INCLUDED
#define THING_H_INCLUDED
#include <string>
#include "location.h"
using namespace std;
class Thing //superclass that will be the base for objects
{
protected:
Location * loc; //location (in or out of map)
string name; //name
string desc; //description
bool deletable; //deletable (for undestructible items)
bool takeable; //if you can put it in your inv
bool hasInv; //returns true if the item has an inventory
public:
//constructor/destructor (debug only)
Thing() //sets initial values
{loc = new Location(0, 0);
name = "Uninitialized";
deletable = takeable = true;
}
Thing(int ix, int iy) //sets location
{loc = new Location(ix, iy);
name = "Uninitialized";
deletable = takeable = false;}
~Thing() {delete loc;} //deletes allocated data
//getters
Location* getLoc() {return loc;} //returns the location
string getDesc(){return desc;} //returns the description
bool getDel(){return deletable;} //returns deletable status
bool getTake(){return takeable;} //returns takeable status
string getName(){return name;} //returns name
string dispLoc(){return loc->getloc();} //displays location
//setters
void setName(string s){name = s;} //sets name
void setDel(bool b){deletable = b;} //sets deletability
void setDesc(string d) {desc = d;} //sets desc
void setLoc(Location* l) {loc = l;} //sets loc
void setTake(bool b){takeable = b;} //sets takeability
//accessors
};
#endif // THING_H_INCLUDED
I believe this is because you have recursive dependincies. That is, your classes all depend on each other, which means that at some point one of the classes will not be able to compile, because in order to get compiled it will need declaration of a class, but, it will not be able to find the declaration, because it is in the header file that is already up there in the stack of "#include" and thus because of guarding "#ifdef" becomes empty.
To give you the example.
To compile Tile, you need declaration of Location, so, naturally, you #include "location.h". But, to compile declaration of Location, you need declaration of Tile, so, you #include "Tile.h". But Tile.h has been #include-ed already, so there is no declaration for it!
The way to fight such circular dependencies is to use incomplete class declaration. For example, instead of including location.h into Tile.h, write
class Location;
class Tile
{
Location* loc;
}
This works as long as Location is only used to declare a pointer or reference and no members of Location class are accessed.
Then, in you 'Tile.c' file you can #include "location.h" and allow your inplementation of Tile methods access to Location members.
You have an include-loop
Tile.h includes
location.h
Thing.h
Container.h
Container.h includes Thing.h
Thing.h includes location.h
location.h includes Tile.h
Oops.
So let us say in the .cpp, the first to be included is Container.h. Then that includes Thing.h before it declares anything. Thing.h in turn includes location.h before it declares anything. Then that includes Tile.h before it declares anything. In Tile.h, all the include guards make the recursive includes no-ops.
And thus in Tile.h, Thing and Container are unknown.