Search code examples
c++scopeinclude

class not declared in scope - even though .h was included


i am relatively new to c++ and I am running into an odd issue,

I am getting "ToDoItem was not declared in this scope" yet I have included the todoitem.h file

the error is in this class definition:

#ifndef ITEMMONITOR_H
#define ITEMMONITOR_H

#include <QObject>
#include <QPointer>
#include <QTimer>
#include "todoitem.h"

class ItemMonitor : public QObject{
    Q_OBJECT

    signals:
        void finished();

    public:
        explicit ItemMonitor(std::vector< QPointer<ToDoItem> >&  items_);

    private:
        std::vector< QPointer<ToDoItem> >& items;
        bool shouldRun;

    public slots:
        void beginMonitoring();
        void finishUp();
};

#endif // ITEMMONITOR_H

and the todoitem.h is:

#ifndef TODOITEM_H
#define TODOITEM_H


#include <string>
#include <QString>
#include <QPushButton>
#include <QFrame>
#include <QDateTime>
#include "todolist.h"


namespace Ui {
    class ToDoItem;
}

class ToDoItem : public QFrame{
    Q_OBJECT

    public:
        //constructor and destructor
        explicit ToDoItem(QFrame *parent = 0);
        ~ToDoItem();

        //functions
        void setValues(QString mainText_,          // sets all import
                   QString additionalText_,
                   QDateTime dateTime_,
                   bool hasDeadline_);
        void paintEvent(QPaintEvent *pe);          //added to support stylesheets
        void setDeadline(QDateTime deadline_);
        QDateTime getDeadline();
        bool getHasDeadline();
        void setId(int id_);
        int getId();
        void setSecsTillDeadline();
        int getSecsTillDeadline();
        bool getSorted();
        void setSorted(bool sorted_);
        QString getMainText();
    private:
        QString formatTime(int duration_);
        Ui::ToDoItem *ui;
        int id;
        QDateTime deadline;
        bool hasDeadline;
        int secsTillDeadline;
        bool sorted;                               // set to true only during the sorting process
};

#endif // TODOITEM_H

Solution

  • The common circular include problem occurs with:
    a.h

    #ifndef A_H
    #define A_H
    #include "b.h"
    // do something requiring content from b.h
    #endif  
    

    b.h

    #ifndef B_H
    #define B_H
    #include "a.h"
    // whatever
    #endif  
    

    If some cpp includes "a.h" you might get away with it (if b.h didn't really need a.h). But if that cpp instead includes b.h then b.h includes a.h BEFORE declaring things needed by a.h. Then a.h tries to include b.h but the include guard blocks that, so the compiler processes a.h without the declarations from b.h and fails.

    That common problem is often masked by another layer, as it was in your example: todoitem.h included "todolist.h", even though it didn't really need it, then "todolist.h" included "intemmonitor.h" which needed "todoitem.h" but failed to include it due to the include guard.