I get the following error when I try to execute this code segment : "Menu does not name a type".I know its something to do with the circular references, but for the life of me I can't figure out what. Also, menu, go, and manager are repeatedly giving errors. The code segments are posted below :
#ifndef GO__H
#define GO__H
#include <SDL.h>
#include <iostream>
#include <string>
using std::cout; using std::endl;
using std::string;
#include "ioManager.h"
#include "gui.h"
#include "clock.h"
#include "menu.h"
//class Menu;
class Go {
public:
Go ();
void play();
private:
SDL_Surface *screen;
Gui gui;
Menu menu;
void drawBackground() const;
Go(const Go&);
Go& operator=(const Go&);
};
#endif
Here's Menu :
#ifndef MENU_H
#define MENU_H
#include <SDL.h>
#include <iostream>
#include "ioManager.h"
#include "gui.h"
#include "clock.h"
#include "manager.h"
class Menu {
public:
Menu ();
void play();
private:
const Clock& clock;
bool env;
SDL_Surface *screen;
Gui gui;
Manager mng;
void drawBackground() const;
Menu(const Menu&);
Menu& operator=(const Menu&);
};
#endif
Manager :
#ifndef MANAG_H
#define MANAG_H
#include "go.h"
class Manager {
Go go;
//other code
}
Can you see where the problem is? Error message:
In file included from go.h:13:0,
from manager.h:33,
from manager.cpp:2:
menu.h:28:11: error: field ‘mng’ has incomplete type
manager.h includes go.h which includes menu.h which includes manager.h ...
The class Menu is being defined before it ever gets to the definition of class Manager.
However, class Menu needs a Manager but since the compiler doesn't know about Manager yet it doesn't know how big to make it.
You could forward declare class Manager and make the mng member of Menu a pointer or reference:
class Manager;
class Menu {
...
Manager* mng;
// or this:
//Manager& mng;
...
Here's a good explanation of circular references and how to fix them.
It appears you are missing the semicolon at the end of the declaration of your Manager class in manger.h.
You are also missing the #endif to close your include guard.
Related
Please note that I have looked at other questions on stack overflow before posting this question. I have not found any solutions that worked.
(This is simplified)
I have five files:
assets.h
#pragma once
#include "SDL2/SDL.h"
#include <map>
#include <string>
// Asset Manager class
class AssetManager {
private:
std::map<std::string, SDL_Texture*> textures;
public:
AssetManager();
~AssetManager();
void addTexture(std::string id, const char *path);
SDL_Texture *getTexture(std::string id);
};
assets.cpp
#include "assets.h"
// Constructor
AssetManager::AssetManager() {}
// Destructor
AssetManager::~AssetManager() {
// Destructor code
}
// Adds texture to "textures"
void AssetManager::addTexture(std::string id, const char *path) {
// Code for adding texture
}
// Gets texture from "textures"
SDL_Texture *AssetManager::getTexture(std::string id) {
// Code for getting texture
}
game.h
#pragma once
class AssetManager; // assets.h include in game.cpp (see below)
class Game {
private:
// Code here
public:
static AssetManager *assets;
// More code here
};
game.cpp
#include "assets.h"
#include "game.h"
AssetManager *Game::assets = new AssetManager();
// Code for game here
other_file.cpp
#include "game.h"
Game::assets->getTexture[<id>] // <-- This is where the error comes from
Even though I used a forward decleration of class "AssetsManager" in game.h, and then included assets.h in game.cpp, when included from other files it gives this error:
error: invalid use of incomplete type 'class AssetManager'
Why does it say "AssetManager" is an incomplete type?
Turns out I was missing a #include statement in other_file.cpp.
This is driving me insane, I have a class called Model, a class called View, and a header file for something GameCommand. I've included the right header guards and everything as far as I can tell but I keep getting an unknown type name error
Model.h
#ifndef MODEL_H
#define MODEL_H
class Model
{
public:
Model(); //default constructor
};
#endif
Model.cpp
#include "Model.h"
#include <iostream>
using namespace std;
Model::Model() //default constructor
{
whatever
}
View.h
#ifndef VIEW_H
#define VIEW_H
class View
{
public:
View();
};
#endif
View.cpp
#include "View.h"
#include <iostream>
using namespace std;
View::View()
{ whatever
}
GameCommand.h
#ifndef GAMECOMMAND_H
#define GAMECOMMAND_H
#include "Model.h"
#include "View.h"
void DoGoCommand(Model&, View&);
error: unknown type name 'Model'
void DoGoCommand(Model&, View&);
^
error: unknown type name 'View'
void DoGoCommand(Model&, View&);
^
I feel like I've tried everything, is there something I am just not seeing here?
You can try to forward declare the classes.
class Model;
class View;
in your GameCommand.h
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;
};
I have an error in my code. All the forums says "in this situation, use Forward Declaration". I tried this and it don't work.
the error is C2079 Credit::mainMenu use a class of MainMenu not declared (translated from french)
I modified the classe to be specific to the question.
main.cpp
#include <SFML/Graphics.hpp>
#include "Menu.h"
#include "credit.h"
#include "mainmenu.h"
MainMenu *mainMenu = new MainMenu();//works here
int main(){
return 0;
}
credit.h
#ifndef DEF_CREDIT
#define DEF_CREDIT
#include <SFML/Graphics.hpp>
#include "Menu.h"
class MainMenu;
class Credit : public Menu
{
private:
MainMenu mainMenu = MainMenu();//DON'T WORK HERE
};
#endif
mainmenu.h
#ifndef DEF_MAINMENU
#define DEF_MAINMENU
#include <SFML/Graphics.hpp>
#include "Menu.h"
#include "credit.h"
class MainMenu :public Menu
{
private:
Credit credit = Credit();//work
};
#endif
Fist i load main.cpp
after the credit.h (there is a credit.hpp but i don't use the variable now)
after the mainmenu.h (there is also a mainmenu.hpp, i don't use variable now)
tip: the Menu class isn't including any of those class
I can send you the complete code if you want
Thanks in advence!
This issue is know as circular dependency. Long story short, two objects should never have another as its subobject.
Instead you have two options. One is to have one point to another
class Credit : public Menu
{
private:
MainMenu* mainMenu;
};
Or, you could have a manager of sorts, where only the manager is aware of both objects, and let them interact through the manager
class Manager
{
private:
Credit credit;
MainMenu mainMenu;
};
For the technical reason why you can't have a member of a declared but not defined type is because it is a incomplete type, and you can't have an object of incomplete type.
what am I doing wrong?
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "fileoperations.h"
namespace Ui {
class MainWindow;
}
class FileOperations;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
FileOperations FileController;
private slots:
void on_OpenButton_clicked();
void on_SaveButton_clicked();
void on_EncodeButton_clicked();
void on_DecodeButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
When i try to compile and run the program, it says:
g:\ke\c++ projects\projects\qt\shitlencoder\mainwindow.h:18: error: C2079: 'MainWindow::FileController' uses undefined class 'FileOperations'
Here's the strange thing, if I change 'FileOperations FileController;' to 'FileOperations *FileController;'(Obviously this compiles wrongly, because the rest of my codes that you can't see havn't been adapted to '->' instead of '.')
Then if I change it back to 'FileOperations FileController;' it lets me compile the program once (And it works fine), then it has the error the next time I try to compile it.
I'm using Qt 5.0.
fileoperations.h:
#ifndef FILEOPERATIONS_H
#define FILEOPERATIONS_H
#include "ui_mainwindow.h"
#include "mainwindow.h"
#include <QFileDialog>
#include <string>
#include <time.h>
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <fstream>
using namespace std;
class FileOperations
{
public:
FileOperations();
void SetInputFile(QString x);
void SetOutputFile(QString x);
void EncryptAndSave(Ui::MainWindow *NUI);
void DecryptAndSave(Ui::MainWindow *NUI);
void createid(int id, int id2);
int GetCFuncion();
void SetCFuncion(int x);
long long Get_Size(string filename);
bool Get_Toobig(string path);
//DWORD WINAPI Thread_no_1();
private:
string InputFilename;
string OutputFilename;
int CFuncion;//CurrentFunction;
vector<int> conbyte1;
vector<int> conbyte2;
vector<int> opbyte1;
vector<int> opbyte2;
vector<int> passwordbytes;
};
#endif // FILEOPERATIONS_H
I assume that, in your .cpp file, you are using
#include "fileoperations.h"
Then, in fileoperations.h, you are including mainwindow.h which again includes fileoperations.h which is basically correct, since you are using a FileOperations object as parameter. But, due to the guards, class FileOperations is not seen by the compiler this time, hence FileOperations is unknown when used as parameter in your method. You need to break this dependency:
In fileoperations.h, use a forward declaration for Ui::MainWindow and remove the #include "mainwindow.h":
namespace Ui {
class MainWindow;
}
...
Since you are holding a FileOperations object in your class, you need the full class declaration. This means you have to include the header, you cannot simply forward declare the class like you are doing now. If you hold only a pointer, and do not have any code in your header that attempts to dereference the pointer, then the forward declaration is enough.
EDIT You have a cyclical include. You are including mainwindow.h in fileoperations.h. You can fix if by removing that include completely.
You have circular include issue, mainwindow.h and fileoperations.h include each other, try to remove below line from fileoperations.h
#include "mainwindow.h"