Qt Error: Can't declared multiple mainwindows in main.cpp - c++

In "main.cpp":
#include "mainwindow.h"
#include "mainwindow_1.h"
And I code in main.cpp:
MainWindow *mainWin_1 = new MainWindow;
MainWindow_1 *mainWin_2 = new MainWindow_1;
I'm already declared MainWindow and MainWindow_1 in "mainwindow.h" and "mainwindow_1.h". They are both QMainWindow. But when I debug, I got an error that said "MainWindow_1 was not declared in this scope".
When I changed:
#include "mainwindow.h"
#include "mainwindow_1.h"
into
#include "mainwindow_1.h"
#include "mainwindow.h"
I got the error "MainWindow was not declared in this scope".
Can I only include one mainwindow? How can I get two QMainwindow in main.cpp without error?
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDateTime>
#include <ctime>
class MainWindow : public QMainWindow {
Q_OBJECT;
public:
MainWindow();
~MainWindow();
};
#endif
mainwindow_1.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDateTime>
#include <ctime>
class MainWindow_1 : public QMainWindow {
Q_OBJECT;
public:
MainWindow_1();
~MainWindow_1();
};
#endif

Sounds like you have same include guard macro in both .h files.
So, change both the #ifndef and #define near beginning of one of the .h files to be different from the include guards of the other .h file.
For example change mainwindow_1.h to have this:
#ifndef MAINWINDOW_1_H
#define MAINWINDOW_1_H
When you have same include guard macro, then the contents of the file included later will be skipped, and the class in it will be left undefined in that .cpp file.
One thing to keep in mind is, C++ include files are not like "import" or such of many other languages. #include just inserts contents of the other file into the compilation, same as if you copy-pasted it. Among other things, this means that later include file "sees" all macros defined in earlier include files, so include guards must have unique names.

Related

can someone help me with the #include being nested to deeply error before i go insane? thx [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed last year.
//main.cpp
#include <iostream>
#include <array>
#include <iomanip>
#include "Board.h"
#include "Game.h"
//Player.h
#include <array>
#include <string.h>
#include <random>
#include "Property.h"
#include "Game.h"
#ifndef Player_h
#define Player_h
//Property.h
#include "Space.h" //#include nested too deeply error
#ifndef Property_h
#define Property_h
//Space.h
#include <sstream>
#include <string>
#ifndef Space_h
#define Space_h
//FreeParking.h + a couple others inheriting from space; there's no error in any of these either
#include "Space.h"
#ifndef FreeParking_h
#define FreeParking_h
//Board.h
#include "Player.h"
#include <array>
#include <random>
#ifndef Board_h
#define Board_h
//Game.h
#include <array>
#include "Property.h"
#include "CommunityChest.h"
#include "Tax.h"
#include "FreeParking.h"
#include "Jail.h"
#include "GoToJail.h"
#include "Go.h"
#include "Player.h"
#ifndef Game_h
#define Game_h
I don't think I made any changes to the #includes today but just got this error even though the program was running fine 20 minutes ago. I only posted the includes because I'm not sure if the actual code matters for this error or not. If it does I'll try to go over the stuff I wrote today, but most of it was just changing things that already worked previously.
Player.h includes Game.h and Game.h includes Player.h. This is an infinite loop. There might be more, but that's just the first one I saw.
You should remove at least one of those includes to break the infinite loop. If you get errors when you do that, you might be able to fix them using a forward declaration that looks something like this:
class Player;
A forward declaration like that would allow you to compile some code that uses the Player class, even though a complete definition of the Player class is not available at that point in the program.
Two more tips to make things more sane:
Put your include guards at the very top of your file before you include anything.
Use #pragma once as the include guard instead of your more complicated thing.

c++ multiple defined in .obj

So I have 3 MFC dialogs:
Dialog1 - main dialog
Dialog2 - sub dialog of Dialog1
Dialog3 - sub dialog of Dialog2
XXXResourceFile.h - resource file used by Dialog2 and Dialog3; contains only resources (macro constants, typedef structs which is used only in the file, and arrays of the typedefed struct); no class
In Dialog1, I need reference of Dialog2 (for showing window/modal).
In Dialog2, I need reference of both Dialog1 ( for calling GetParent() ), and 3 (for showing window/modal)
In Dialog3, I need reference of both Dialog1 and 2 ( for calling GetParent()/ GetAncestor() )
Current design:
//Dialog1.h - by co-dev
...
#include Dialog2.h"
...
//Dialog2.cpp - by co-dev
...
#include "Dialog2.h"
#include "XXXResourceFile.h"
#include "Dialog1.h"
#include "Dialog3.h"
...
//Dialog3.cpp - my initial code/design
...
#include "Dialog3.h"
#include "Dialog2.h"
#include "Dialog1.h"
#include "XXXResourceFile.h"
My ideal design:
//Dialog1.h
#include "Dialog2.h"
...
//Dialog2.h
#include "Dialog1.h"
#include "Dialog3.h"
#include "XXXResourceFile.h"
//Dialog3.h
#include "Dialog1.h"
Now on the current design, I added #pragma once in all of these headers. I am getting error lnk 2005 (says that arrays from the XXXResourceFile is already defined in Dialog3.obj, can't double click on error since it's not on the headers nor source files but on the obj).
My questions are:
Can you comment on the current design and the ideal design of this files? What needs correction, what is missing, etc...
I don't think I've fully understood usage of #pragma once. In my knowledge (also based on what my co-devs say), it is included only in header files. What about cpp files?
Also since my problem is the inclusion of XXXResourceFile.h, is the correct usage of #pragma once supposed to be on this header? Or the files that will include this header? This bit is the part where I'm really confused.
You have header circular dependency here:
//Dialog1.h
#include "Dialog2.h"
...
//Dialog2.h
#include "Dialog1.h"
#include "Dialog3.h"
#include "XXXResourceFile.h"
//Dialog3.h
#include "Dialog1.h"
Dialog1.h includes Dialog2.h that includes Dialog1.h.
Dialog1.h includes Dialog2.h that includes Dialog3.h that includes Dialog1.h.
You can break this using forward declarations and pointer types.
// Dialog1.h
class Dialog2;
class Dialog1
{
Dialog2* ptrDialog2;
};
// Dialog1.cpp
#include "Dialog2.h"
// Dialog2.h
class Dialog1;
class Dialog2
{
Dialog1* ptrDialog1;
};
// Dialog2.cpp
#include "Dialog1.h"

C++ header guard not working

I'm trying to get my includes working, but everything I try leads to errors. Even using #pragma once doesn't work. Do you know what I made wrong?
main.cpp
#include "utility/headers/Window.h"
#include "engine/headers/Player.h"
#include "engine/headers/Chunk.h"
ChunkManager.h
#ifndef CHUNK_MANAGER_H
#define CHUNK_MANAGER_H
#include "../../utility/headers/Vector3i.h"
#include "Chunk.h"
#include <map>
class ChunkManager{...}
#endif // CHUNK_MANAGER_H
Chunk.h
#pragma once
#ifndef CHUNK_H
#define CHUNK_H
#include <glm/glm.hpp>
#include "CubeCreator.h"
#include "ChunkManager.h"
#include "../../utility/headers/Random.h"
#include "../../utility/noise/headers/Noise.h"
class Chunk{...}
#endif // CHUNK_H
Error message is 'ChunkManager' has not been declared.
Thanks in advance!
Replace #include "ChunkManager.h" with class ChunkManager;.
That's called forward declaration and solves problems like class A needs to know about class B and class B needs to know about class A.
Depending on how you use ChunkManager in class Chunk. A forward declaration might not work.
Since non of the mentioned techniques worked in my case I defined a new header file containing global variables like chunkSize. Maybe it's just impossible to do what I've tried.
However for those who might find this question here's how my imports look now:
ChunkManager.h
#include "Chunk.h"
Chunk.h
// no includes
main.cpp
#include "ChunkManager.h"
And access to chunkSize isn't done anymore by calling ChunkManager::chunkSize but instead by calling Settings::chunkSize

C++ Header Guards

Suppose I have the following header file:
#ifndef TESTCLASS_H
#define TESTCLASS_H
#include <string>
class TestClass
{
public:
TestClass();
std::string test();
};
#endif // TESTCLASS_H
Do I have to put a guard around #include <string> as well? If not, what if main.cpp also has #include <string>?
No, because the string header file has got its own include guards (as do the header files of all sensible libraries).
Not necesarry, the c++ standard libs have their own Guards.

Circular dependencies with headers. Using #ifndef and #define

I have the very simple following code:
main.cpp
#include "ui_library_browser.h"
#include <QtGui/QApplication>
#include "StartWindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
StartWindow w;
w.show();
return a.exec();
}
StartWindow.h
#ifndef STARTWINDOW_H_
#define STARTWINDOW_H_
#include <qwidget>
#include "MainWindow.h"
class StartWindow : public QWidget
{
Q_OBJECT
public:
StartWindow();
~StartWindow();
MainWindow main_window; //<-- Problem
};
#endif
MainWindow.h
#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#include <qdialog.h>
#include "StartWindow.h"
class MainWindow : public QDialog
{
Q_OBJECT
public:
MainWindow();
~MainWindow();
};
#endif
This produces errors because of the inclusion of #include "StartWindow.h" in the MainWindow.h header. However, I thought the use of #ifndef and #define are to stop problems like this? Can someone clear this up for me?
So called "header guards" are used to prevent a bit different kind of error: including same header multiple time through different indirect inclusions in one compile unit. For example,
you include "a.h" from main.cpp and then include "b.h" from main.cpp, that includes "a.h" itself somewhere inside.
In your case two headers try to include each other circurally, that is not possible - C/C++ preprocessor works as simple text "copy-paste" and this case would invent infinite recursion of text insertion.
And I really don't see why would you need "StartWindow.h" inclusion in "MainWindow.h" header.
Do you use StartWindow in MainWindow? If not, simply remove the StartWindow.h include. Otherwise make the main_window a pointer instead of a variable.
In the file StartWindow.h remove #include "MainWindow.h" and add the forward declaration (before class StartWindow ...):
class MainWindow;
In the same file change the member MainWindow main_window to
const MainWindow* main_window;
or
const MainWindow& main_window;
In the latter case you would need to pass const MainWindow& in the constructor of StartWindow.