[Solved] definition of ... is not in namespace enclosing ... - Why?
-
Hi!
I am trying to reuse a small application for some different behavior. So far it's not much more than some easy serial communication so I was relying on the Qt Terminal demo. The reused application works fine, so I copied that, moved it to a different folder and adjusted the project file. It opens fine, then I removed much stuff I think I don't need. But now I get this error:
Fehler: definition of 'MainWindow::MainWindow(QWidget*)' is not in namespace enclosing 'MainWindow' [-fpermissive] MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
MainWindow is the name I gave to - have a guess ;) - the main window. The constructor is defined as this:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle( windowTitle() + Constants::STR_SPACE + Constants::VERSION ); setWindowIcon( QIcon( Constants::ICON_PATH ) ); ...
The header file looks like this:
#include <QtCore/QtGlobal> #include <QMainWindow> #include <QtSerialPort/QSerialPort> #include <QLabel> #include <QTimer> #include "ServiceTools_Shared_Qt/Component/autostatemachine.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class SettingsDialog; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void openSerialPort(); ...
I have no idea what this compiler error is trying to tell me? Can anyone point me to the right direction?
BTW: I am pretty new to Qt, so I hope the question is not to dull? ;)
Thanks a lot & Regards,
Stephan Wöbbeking -
As you can see there's this forward declaration in your header:
namespace Ui { class MainWindow; }
The latter declaration of the MainWindow class is not in that namespace and that's what the compiler is complaining about.
But don't go removing that forward declaration just yet. It's needed ;)You probably have a .ui designer file associated with that class. It's probably named mainwindow.ui or whatever it was before you renamed your class. The moc tool generates from it a header called ui_mainwindow.h (or whatever the name was before). This file contains the definition of the Ui::MainWindow class that is the type of the ui variable you see in your code.
You said you removed stuff and there's probably this one line you shouldn't have ;) #include that ui_mainwindow.h file in the MainWindow.cpp and it should compile fine. -
A good look at the docs might reveal a different method of declaring your designer form similar to this:
mainwindow.hpp
#include <QtCore/QObject> #include <QtWidgets/QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public MainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent=0); virtual ~MainWindow(); . . . private: class PrivateData; PrivateData *d_data; Ui::MainWindow *ui; };
mainwindow.cpp
#include "mainwindow.hpp class MainWindow::PrivateData { // your private vars }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { d_data = new PrivateData; ui = new MainWindow(this); ui->setupUi(); ui->retranslateUi(); // any reference to widgets on the // designer form are in the form // ui->form_widget . . . } MainWindow::~MainWindow() { delete ui; delete d_data; }
This C++ "pimpl" pattern will allow you to have back-end protection and not break compatibility when most form or private data changes are made as well as other significant protections. There are a number of alternate patterns you could use. However, again, I would follow the docs and the coding guidelines provided directly in the docs as well as the KDE binary compatibility guidelines as well.
Just a thought.
-
Hi, thanks for the answers!
I must admit all you wrote made some sense to me, even I didn't understand it completely I confess. I was trying to understand the implications between all these issues but always came to the result, that I haven't changed anything in that structure with respect to my "prototype".
However, just by chance, I found in a completely different file (a constants definition file), that a closing brace ('}') was missing. That seems to have totally confused the compiler - which I would not have thought. I had reckoned that it would be more stable to such issues and point to the right file / issue more precisely, but the produced messages where totally misleading. At least to me.
Never mind, it seems that issue is solved and the next comes around the corner. ;) So I have to work on that and call back on it maybe.
Thanks again and Regards,
Stephan -
Stephan
Well it turn out the compiler and sometimes the linker are confused by relatively benign omissions - like the semi-colon after a class definition.
Also the resulting error messages are not always helpful as in the case above.
It is a good rule of thumb to learn and closely follow the coding guidelines given in the docs and supplemental publications (like the KDE document mentioned earlier). That way you can learn to spot these omissions that do not follow the guidelines and will me more obvious in the future.