'Cashier' was not declared in this scope - c++

I have this piece of code
#ifndef STATION_H
#define STATION_H
#include <vector>
#include "Dispenser.h"
#include "Cashier.h"
//class Cashier;
class Station
{
private:
int price;
int dispenser_count;
int cashier_count;
std::vector<Dispenser> dispensers;
std::vector<Cashier> cashiers;
public:
Station(int, int, int);
int GetPrice() const { return price; }
Dispenser *LookForUnoccupiedDispenser(int &id);
Dispenser *GetDispenserByID(int id);
Cashier *LookForUnoccupiedCashier();
};
#endif // STATION_H
When I have the class Cashier line commented, the compiler fails with a 'Cashier' was not declared in this scope error even though Cashier.h was included. Uncommenting it makes it possible to compile but I'm concerned that it shouldn't be happening.
Cashier.h
#ifndef CASHIER_H
#define CASHIER_H
#include "Station.h"
class Station;
class Cashier
{
private:
bool busy;
Station *at_station;
public:
Cashier(Station *employer);
bool IsBusy() const { return busy; }
};
#endif // CASHIER_H
How is it possible? It's clearly declared in the header file and as far as I know, #include does nothing more than pasting the content of a file into another one.
Thank you for the answers in advance!

Your station.h includes cachier.h. This is an example of cyclic dependency. Given that you only have a pointer to Station in Cachier I'd suggest removing the dependency of station.h and forward declare it.
An #include is literally nothing more than verbatim copy and paste of that file into the current compilation unit. The guards protect you from the effect of an infinite include cycle, but due to the guards one of the #includes does nothing, i.e. does NOT suck in the declaration (nor definition) of the respective class. This results in the error you get. In station.h the compiler has never seen any mention of the Cachier type when it sees the Station type.

Related

Base class undefined, but its header is included

I'm having some troubles where a function isn't returning the right type, because a class isn't defined. I'm using a factory pattern.
The two error messages that I'm getting are:
'return': cannot convert from 'DLA *' to 'Layer *'
and:
'Layer': base class undefined (compiling source file src\Layer.cpp)
and this same error message is repeated for every file that includes Layer.h.
Here is what my class that inherits from Layer looks like (DLA.h):
#pragma once
#ifndef _DLA
#define _DLA
#include "ofMain.h"
#include "ofxGui.h"
#include "Layer.h"
class DLA: public Layer
{
public:
DLA();
void setup();
void update();
void draw();
private:
};
#endif
and here is my Layer class header (Layer.h):
#pragma once
#ifndef _LAYER
#define _LAYER
#include "ofMain.h"
#include "ofxGui.h"
#include "DLA.h"
enum SceneType
{
Scene_None,
Scene_Default,
Scene_DLA,
};
class Layer
{
public:
void setup();
void update();
void draw();
static Layer *CreateSimulation(SceneType Type);
private:
};
#endif
The function which is failing is this one, situated in Layer.cpp:
Layer *Layer::CreateSimulation(SceneType Type)
{
switch (Type)
{
case Scene_None:
default:
return nullptr;
case Scene_DLA:
return new DLA();
}
}
I've tried everything I could find on Stack Overflow that had similar issues to mine but I've seen some people recommend very subtle code indentation to fix this, so I'm really lost as to find where the problem is.
As they stand, your header files induce circular dependency, even though the #pragma once (and other) guards prevent any actual 'infinite recursion'. Let's look at the sequence of code, from the compiler's point-of-view, when compiling the Layer.cpp file (or any other '.cpp' source that has #include "Layer.h" in it).
The compiler encounters #include "Layer.h" (the first time it has done so - the guards won't be 'triggered'), so it duly replaces that line with the contents of the indicated header. In that content, it encounters #include "DLA.h" (we can ignore the other headers included in this discussion, assuming that they aren't relevant to the problem in hand). So, it then duly replaces that line with the contents of the DLA.h header, at which point it will come across this:
#include "Layer.h"
class DLA: public Layer
{
Now, here, when it replaces #include "Layer.h" with the header content, that content will be 'empty' (because of the guards, as it has already included that header once). Thus, when the public Layer code is encountered, it is an error, because that class has not yet been defined, or even declared as a class.
So, if you really insist on having the #include "DLA.h" line in Layer.h, then it must be placed after the definition of the Layer class.
However, a far better way would be to remove #include "DLA.h" from Layer.h, and only place it in source (.cpp) files that actually need it (like Layer.cpp). This would work well:
// Layer.cpp
#include "Layer.h"
#include "DLA.h" // At this point, references to the Layer class in DLA.h will be fine!
//...
Layer *Layer::CreateSimulation(SceneType Type)
{
switch (Type)
{
case Scene_None:
default:
return nullptr;
case Scene_DLA:
return new DLA();
}
}
Feel free to as k for any further clarification and/or explanation.

How is it possible that I can make an instance from a class in which some member methods aren't defined yet? (C++)

I'm comparatively new to C++ so I tested some things out in Xcode, and found a really weird thing.
This is my 'Testing.h' file
#ifndef Testing_h
#define Testing_h
class Testing{
private:
int a;
public:
Testing(int a=3);
void hey(int b);
};
#endif
This is my 'Testing.cpp' file
#include "Testing.h"
Testing::Testing(int a){
a = 4;
}
And finally, this is the 'main.cpp' file
#include <iostream>
#include "Testing.h"
using namespace std;
int main(){
Testing a;
//Apparently not completing the definitions of every abstract methods in the class is not a problem
}
I only declared 'void hey(int b)' in 'Testing.h' but have not defined it in 'Testing.cpp'. So I was wondering how it is possible for the compiler to successfully compile the 'main.cpp' without having enough information of 'void hey(int b)'. Thanks in advance!
Because you never require there to be a definition for hey().
You can require a definition by calling it, for example :
a.hey(42);
And you'll see that the linker isn't too happy because hey is an undefined reference.
Testing a;//Apparently not completing the definitions of every abstract methods in the class is not a problem
You defined constructor with default value a=3 but calling both constructor argument and class parameter the same name is bad practice.
Instead you can write this:
//Testing.h
#ifndef Testing_h
#define Testing_h
using namespace std;
class Testing{
private:
int number;
public:
Testing(int a=3): number(a = 4){}//it's the same as your implementation in cpp file
void hey(int b);
int getNumber() {return number;}
};
#endif
//main.cpp
#include <iostream>
#include "Testing.h"
int main()
{
Testing object;
cout<<object.getNumber();// returns 4
return 0;
}
And why hey compiles?
During building your project compiler translates your source code into object code by verifying the syntax. After that process linker checks the definitions marked by whole phrases. Source code is compiled from each file provided. Linker doesn't care for the implementation presence, it only looks it up if a method is used by the program. So even without implementation of hey your program compiles.
Last remark
It's discouraged to include .cpp files use headers instead. Sometimes you can get yourself into multiple definitions of the same functions causing compiler errors.

setter in class won't set variable

I'm currently trying to make a game in C++. In my code I'm trying to nest my variables so that my main doesn't have a lot of includes. My problem right now though is that the value of my variables in my class aren't changing. Stepping through the code it shows it setting the value, but it doesn't work. Anyone know what's going on? Thank you in advance.
This is what I have so far:
Location.h
#ifndef LOCATION_H
#define LOCATION_H
#include <string>
class Location
{
public:
Location(void);
Location(std::string name);
~Location(void);
std::string GetName();
void SetName(std::string value);
private:
std::string m_Name
};
#endif
Location.cpp
#include "Location.h"
Location::Location(void): m_Name("") {}
Location::Location(std::string name): m_Name(name) {}
Location::~Location(void)
{
}
std::string Location::GetName()
{return m_Name;}
void Location::SetName(std::string value){m_Name = value;}
PlayerStats.h
#ifndef PLAYERSTATS_H
#define PLAYERSTATS_H
#include "Location.h"
class PlayerStats
{
public:
PlayerStats(void);
~PlayerStats(void);
Location GetLocation();
void SetLocation(Location location);
private:
Location m_Location;
};
#endif
PlayerStats.cpp
#include "PlayerStats.h"
PlayerStats::PlayerStats(void): m_Location(Location()) {}
PlayerStats::~PlayerStats(void)
{
}
Location PlayerStats::GetLocation(){return m_Location;}
void PlayerStats::SetLocation(Location location){m_Location = location;}
main.cpp
#include <iostream>
#include "PlayerStats.h"
using namespace std;
PlayerStats playerStats = PlayerStats();
int main()
{
playerStats.GetLocation().SetName("Test");
cout<< playerStats.GetLocation().GetName()<<endl;
return 0;
}
Your immediate issue is that
Location GetLocation();
returns a copy of the location, so when you call SetName here:
playerStats.GetLocation().SetName("Test");
You're changing the name of the temporary copy, and the change is lost as soon as the semicolon is hit.
More broadly, this kind of design (nesting classes and nesting includes so that main doesn't have a lot of includes, and using a.b.c() style code to access nested members) isn't great C++ style:
Having a bunch of source files that (transitively) include a bunch of header files means that changing a single header file will trigger recompilations of a bunch of source files. Compile times can be a significant issue in larger C++ projects, so reducing compile times by controlling #include's is important. Read up on "forward declarations" for more information.
Writing code like a.b.c() is considered bad object-oriented design, because it reduces encapsulation: not only does the caller have to know about a's details, it has to know about b's also. Sometimes this is the most expedient way to write code, but it's not something to be blindly done just to reduce #include's. Read up on "Law of Demeter" for more information.
If you want to set the result of playerStats.GetLocation(), you could make GetLocation() pass-by-reference (use ampersand, &, on the return argument). Otherwise you are just setting values in a temporary copy of PlayerStats::m_Location.
Alternatively, you could use the SetLocation() function.

c++ how declare function returning vector of objects

and I struggle with function which should return vector of objects but for some reason it throws errors all the time, telling that my object is undeclared identifier and vector of this objects is not valid template and points me to .h file where I declare function.
I will appropriate any explanation what that mean and how to fix this. bellow I place code from my class and starting files.
#ifndef SETUPW_H
#define SETUPW_H
#include"Square.h"
#include <iostream>
#include<string>
#include<fstream>
#include<vector>
std::vector<std::ifstream> allText();
std::ifstream loadTxt(std::string txt);
void printByLine(std::ifstream& txt);
std::vector<square> allSquares();//compiler points me to this line and that one bellow
void whichSQ(int sqNum, std::vector<square> sq);
#endif
and my class:
#ifndef SQUARE_H
#define SQUARE_H
#include"player.h"
#include"setupW.h"
#include<iostream>
#include<string>
#include<fstream>
class square
{
public:
square(std::string name, int sqNumber, std::string description, int exits, int object);
void loadSQ(std::ifstream& inFile);
void printSQ();
private:
int mSqNumber;
std::string mName;
std::string mDescription;
int mExits;
int mObject;
};
#endif
The problem arises because you have a circular dependency here. In square.cpp you firstly include square.h. But square.h contains this line #include"setupW.h" (before your class declaration). Therefor the declarations of your functions will appear before the declaration of your square class. That causes the compiler to mutter that square is not declared (at that time) when he reads std::vector<square>.
The most easiest solution would be to simply remove the include, because it is, as far as I can tell, unneccessary.

Another 'x was not declared in this scope'

this is my first question here.
Writing some code, i receive this error from g++: "Entity was not declared in this scope", in this context:
#ifndef Psyco2D_GameManager_
#define Psyco2D_GameManager_
#include <vector>
#include "Entity.h"
namespace Psyco2D{
class GameManager{J
private:
std::vector<Entity> entities;
};
}
#endif
This is the content of Entity.h:
#ifndef Psyco2D_Entity_
#define Psyco2D_Entity_
#include <string>
#include "GameManager.h"
#include "EntityComponent.h"
namespace Psyco2D{
class Entity{
friend class GameManager;
private:
/* Identificatore */
std::string _name;
/* Components list */
std::map<const std::string, EntityComponent*> components;
protected:
Entity(const std::string name);
public:
inline const std::string getName() const{
return this->_name;
}
void addComponent(EntityComponent* component, const std::string name);
EntityComponent* lookupComponent(const std::string name) const;
void deleteComponent(const std::string name);
};
}
#endif
If i use std::vector<class Entity> instead of std::vector<Entity> it works.
Why?
Thanks to all =)
The problem is you have a cyclic dependency. Take out #include "GameManager.h" in Entity.h, since you don't actually need it in that header. (Up-vote this answer, which first pointed it out.)
Note the guards are actually the problem; but don't take them out! You just need to minimize the includes you have, and declare (and not define) types when possible. Consider what happens when you include Entity.h: As some point it includes GameManager.h, which in turn includes Entity.h. At this point, Entity.h already has its header guard defined, so it skips the contents. Then the parsing of GameManager.h continues, where upon it runs into Entity, and rightfully complains it is not defined. (Indeed, this is still the process of including GameManager.h in the first inclusion of Entity.h, far before Entity is defined!)
Note your numerous edits demonstrate why it's important to post real code, not re-synthesized code. You need real details to get real answers.
Old:
Entity is in the Psyco2D namespace. You need to specify that:
class GameManager{
private:
std::vector<Psyco2D::Entity> entities;
};
Assuming the first snippet is part of GameManager.h you have a circular header dependency. I believe you can fix this by changing the GameManager.h include in Entity.h to class GameManager; instead.
Additionally as GMan noted, Entity is in a namespace and you need to qualify Entity with the namespace name.
Remove the Psyco2D-namespace and it will work without declaring "class Entity".