Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. forward declarations give errors + I want some explanation
Forum Updated to NodeBB v4.3 + New Features

forward declarations give errors + I want some explanation

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 2.6k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #2

    hi
    when you say
    class QLabel;
    its ok to use it for pointers.

    QLabel *myname;

    But if you start to use ANYTHING in it
    like
    myname->setBuddy

    then a forward is NOT enough and u must include the include file for it
    #include <QLabel>

    So that is what incomplete class error means.

    as you only tell it the name. and if u use more than name, you must give compiler the full class definition.

    S 1 Reply Last reply
    2
    • ValentinMicheletV Offline
      ValentinMicheletV Offline
      ValentinMichelet
      wrote on last edited by
      #3

      In addition to what @mrjj said, it's a good practice to use forward declaration in your .h file, but you have to add #include <QLabel> in your .cpp for the reasons mrjj gave you. Indeed, the compiler is complaining about your .cpp file, not your .h file.

      But for instance, if you don't use a pointer for your variable, or if you inherit from an other class, then you have to #include it, since the compiler needs to know extra information about the content of the class.

      1 Reply Last reply
      0
      • mrjjM mrjj

        hi
        when you say
        class QLabel;
        its ok to use it for pointers.

        QLabel *myname;

        But if you start to use ANYTHING in it
        like
        myname->setBuddy

        then a forward is NOT enough and u must include the include file for it
        #include <QLabel>

        So that is what incomplete class error means.

        as you only tell it the name. and if u use more than name, you must give compiler the full class definition.

        S Offline
        S Offline
        SweetOrange
        wrote on last edited by SweetOrange
        #4

        @mrjj
        I added the #includes at finddialog.h:

        #ifndef FINDDIALOG_H
        #define FINDDIALOG_H
        
        #include <QDialog>
        #include <QCheckBox>
        #include <QLabel>
        #include <QLineEdit>
        #include <QPushButton>
        
        class QCheckBox;
        class QLabel;
        class QLineEdit;
        class QPushButton;
        
        class FindDialog : public QDialog
        {
            Q_OBJECT
        
        public:
            FindDialog(QWidget *parent = 0);
        
        signals:
            void findNext(const QString &str, Qt::CaseSensitivity cs);
            void findPrevious(const QString &str, Qt::CaseSensitivity cs);
        
        private slots:
            void findClicked();
            void enableFindButton(const QString &text);
        
        private:
            QLabel *label;
            QLineEdit *lineEdit;
            QCheckBox *caseCheckBox;
            QCheckBox *backwardCheckBox;
            QPushButton *findButton;
            QPushButton *closeButton;
        };
        
        #endif
        
        

        Do I need the forward declarations anymore?

        Also I get the errors:
        http://s11.postimg.org/4izv8mff7/1_20_2016b.jpg
        which I suspect that I haven't included the include files for QHBoxLayout and QVBoxLayout.
        In which file do I include these?

        ValentinMicheletV 1 Reply Last reply
        0
        • S SweetOrange

          @mrjj
          I added the #includes at finddialog.h:

          #ifndef FINDDIALOG_H
          #define FINDDIALOG_H
          
          #include <QDialog>
          #include <QCheckBox>
          #include <QLabel>
          #include <QLineEdit>
          #include <QPushButton>
          
          class QCheckBox;
          class QLabel;
          class QLineEdit;
          class QPushButton;
          
          class FindDialog : public QDialog
          {
              Q_OBJECT
          
          public:
              FindDialog(QWidget *parent = 0);
          
          signals:
              void findNext(const QString &str, Qt::CaseSensitivity cs);
              void findPrevious(const QString &str, Qt::CaseSensitivity cs);
          
          private slots:
              void findClicked();
              void enableFindButton(const QString &text);
          
          private:
              QLabel *label;
              QLineEdit *lineEdit;
              QCheckBox *caseCheckBox;
              QCheckBox *backwardCheckBox;
              QPushButton *findButton;
              QPushButton *closeButton;
          };
          
          #endif
          
          

          Do I need the forward declarations anymore?

          Also I get the errors:
          http://s11.postimg.org/4izv8mff7/1_20_2016b.jpg
          which I suspect that I haven't included the include files for QHBoxLayout and QVBoxLayout.
          In which file do I include these?

          ValentinMicheletV Offline
          ValentinMicheletV Offline
          ValentinMichelet
          wrote on last edited by ValentinMichelet
          #5

          @SweetOrange

          Look at the file on the right of the error message, you'll know where to #include what the compiler lacks.

          1 Reply Last reply
          1
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #6

            Hi in 99% of all cases the include has same name as class.
            #include <QVBoxLayout>
            and no, no need for forward when u use the real include.

            1 Reply Last reply
            1
            • ValentinMicheletV Offline
              ValentinMicheletV Offline
              ValentinMichelet
              wrote on last edited by
              #7

              Maybe it's a bit technical, but here is a link on Stack Overflow explaining what a forward declaration is:
              http://stackoverflow.com/questions/553682/when-can-i-use-a-forward-declaration

              Basically, a forward declaration is only a "Don't worry compiler, this class exists." statement. As soon as the implementation of the class is required, the #include is mendatory.

              The question of "should I use #include or forward declaration here?" is off topic tho.

              1 Reply Last reply
              1
              • S Offline
                S Offline
                SweetOrange
                wrote on last edited by
                #8

                Thanks for the info.

                #ifndef FINDDIALOG_H
                #define FINDDIALOG_H
                
                #include <QDialog>
                #include <QLabel>
                #include <QLineEdit>
                #include <QCheckBox>
                #include <QPushButton>
                
                //class QCheckBox;
                //class QLabel;
                //class QLineEdit;
                //class QPushButton;
                
                class FindDialog : public QDialog
                {
                    Q_OBJECT
                
                public:
                    FindDialog(QWidget *parent = 0);
                
                signals:
                    void findNext(const QString &str, Qt::CaseSensitivity cs);
                    void findPrevious(const QString &str, Qt::CaseSensitivity cs);
                
                private slots:
                    void findClicked();
                    void enableFindButton(const QString &text);
                
                private:
                    QLabel *label;
                    QLineEdit *lineEdit;
                    QCheckBox *caseCheckBox;
                    QCheckBox *backwardCheckBox;
                    QPushButton *findButton;
                    QPushButton *closeButton;
                };
                
                #endif
                
                
                #include <QtGui>
                
                #include "finddialog.h"
                #include <QHBoxLayout>
                #include <QVBoxLayout>
                
                
                
                
                
                
                FindDialog::FindDialog(QWidget *parent)
                    : QDialog(parent)
                {
                    label = new QLabel(tr("Find &what:"));
                    lineEdit = new QLineEdit;
                    label->setBuddy(lineEdit);
                
                    caseCheckBox = new QCheckBox(tr("Match &case"));
                    backwardCheckBox = new QCheckBox(tr("Search &backward"));
                
                    findButton = new QPushButton(tr("&Find"));
                    findButton->setDefault(true);
                    findButton->setEnabled(false);
                
                    closeButton = new QPushButton(tr("Close"));
                
                    connect(lineEdit, SIGNAL(textChanged(const QString &)),
                            this, SLOT(enableFindButton(const QString &)));
                    connect(findButton, SIGNAL(clicked()),
                            this, SLOT(findClicked()));
                    connect(closeButton, SIGNAL(clicked()),
                            this, SLOT(close()));
                
                    QHBoxLayout *topLeftLayout = new QHBoxLayout;
                    topLeftLayout->addWidget(label);
                    topLeftLayout->addWidget(lineEdit);
                
                    QVBoxLayout *leftLayout = new QVBoxLayout;
                    leftLayout->addLayout(topLeftLayout);
                    leftLayout->addWidget(caseCheckBox);
                    leftLayout->addWidget(backwardCheckBox);
                
                    QVBoxLayout *rightLayout = new QVBoxLayout;
                    rightLayout->addWidget(findButton);
                    rightLayout->addWidget(closeButton);
                    rightLayout->addStretch();
                
                    QHBoxLayout *mainLayout = new QHBoxLayout;
                    mainLayout->addLayout(leftLayout);
                    mainLayout->addLayout(rightLayout);
                    setLayout(mainLayout);
                
                    setWindowTitle(tr("Find"));
                    setFixedHeight(sizeHint().height());
                }
                
                void FindDialog::findClicked()
                {
                    QString text = lineEdit->text();
                    Qt::CaseSensitivity cs =
                            caseCheckBox->isChecked() ? Qt::CaseSensitive
                                                      : Qt::CaseInsensitive;
                    if (backwardCheckBox->isChecked()) {
                        emit findPrevious(text, cs);
                    } else {
                        emit findNext(text, cs);
                    }
                }
                
                void FindDialog::enableFindButton(const QString &text)
                {
                    findButton->setEnabled(!text.isEmpty());
                }
                
                
                #include <QApplication>
                
                #include "finddialog.h"
                
                int main(int argc, char *argv[])
                {
                    QApplication app(argc, argv);
                    FindDialog *dialog = new FindDialog;
                    dialog->show();
                    return app.exec();
                }
                

                Now works and compiles properly and runs.

                Some explanations though that I found the book lacks. What does the header of the constructor means in finddialog.cpp ?

                FindDialog::FindDialog(QWidget *parent)
                    : QDialog(parent)
                

                This is class inheritance as far as I understand it

                1 Reply Last reply
                0
                • mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #9

                  Hi
                  FindDialog::FindDialog(QWidget *parent)
                  : QDialog(parent) <---- here we call base class constructor with the parent.

                  This is need to setup the part of the class we get from the base class.

                  if u have
                  class A :B

                  then some of A is from B and it might need to do stuff in its constructor.
                  so we call it also.

                  1 Reply Last reply
                  1
                  • S Offline
                    S Offline
                    SweetOrange
                    wrote on last edited by
                    #10

                    Tell me if I am wrong...

                    QDialog is derived from QWidget.

                    The FindDialog constructor is typical of Qt widget classes. The parent parameter specifies the parent widget. The default is a null pointer meaning that the dialog has no parent

                    when we have

                    FindDialog::FindDialog(QWidget *parent)
                       : QDialog(parent)
                    

                    we just say that QDialog is the parent of FindDialog and as mentioned above QWidget is the parent of QDialog.

                    ValentinMicheletV 1 Reply Last reply
                    0
                    • S SweetOrange

                      Tell me if I am wrong...

                      QDialog is derived from QWidget.

                      The FindDialog constructor is typical of Qt widget classes. The parent parameter specifies the parent widget. The default is a null pointer meaning that the dialog has no parent

                      when we have

                      FindDialog::FindDialog(QWidget *parent)
                         : QDialog(parent)
                      

                      we just say that QDialog is the parent of FindDialog and as mentioned above QWidget is the parent of QDialog.

                      ValentinMicheletV Offline
                      ValentinMicheletV Offline
                      ValentinMichelet
                      wrote on last edited by ValentinMichelet
                      #11

                      @SweetOrange

                      Just to be sure that you don't mix up "C++ parent class" and "Qt parent mechanism".

                      In pure C++, a class can inherit from a parent class:

                      class QDialog: public QWidget {}
                      

                      Here the QDialog inherits from QWidget.

                      In Qt, there is a mechanism that makes your life easier for memory managment. You give your class a parent to let it handle the memory in destruction. If you code in C++, you may know that there is no garbage collector as there is in other languages (Java for instance). So as soon as you create an object dynamically - on the heap - using "new" operator, you are responsible for it's destruction using "delete". Qt enables you not to worry about deletion: give your object a parent, and the memory will be handle at its destruction.

                      FindDialog::FindDialog(QWidget *parent): QDialog(parent)
                      

                      Here we call the parent constructor (QDialog) with the parent parameter and we let Qt handle destruction, as well as a provide a way to potential future inherited classes to enjoy this mechanism.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #12

                        Hi,

                        To add to my fellows, you should move:

                        #include <QDialog>
                        #include <QLabel>
                        #include <QLineEdit>
                        #include <QCheckBox>
                        #include <QPushButton>
                        

                        in your implementation file. That's were they are needed in your case.

                        Note that you are using #include <QtGui>, while good for rapid prototyping it's a module wide include which means it will pull in all headers from said module thus your compilation time will increase since all files are going to be parsed.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved