class 未在范围内声明 - 即使包含 .h

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

我对 C++ 比较陌生,我 运行 遇到了一个奇怪的问题,

我得到 "ToDoItem was not declared in this scope" 但我已经包含了 todoitem.h 文件

错误在此 class 定义中:

#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

而 todoitem.h 是:

#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

常见的循环包含问题发生在:
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  

如果某些 cpp 包含 "a.h",您可能会摆脱它(如果 b.h 并不真正需要 a.h)。但是,如果该 cpp 改为包含 b.h,则 b.h 包含 a.h BEFORE 声明 a.h 所需的内容。然后 a.h 尝试包含 b.h 但 include guard 阻止了它,因此编译器在没有来自 b.h 的声明的情况下处理 a.h 并失败。

这个常见问题通常被另一层掩盖,就像在您的示例中一样:todoitem.h 包含 "todolist.h",即使它并不真正需要它,然后 "todolist.h"包含 "intemmonitor.h" 需要 "todoitem.h" 但由于包含保护而未能包含它。

一定要检查每个 header 都有一个与之关联的唯一 #define 值。

复制 header 文件但忘记将 #define HEADER_H 更改为唯一标识符时可能会发生这种情况,因此守卫将阻止包含新的 header 文件,甚至当你 #include 它时。