1. ホーム
  2. c++

[解決済み] .h が含まれているにもかかわらず、スコープで宣言されていないクラスがある。

2022-01-29 19:49:44

質問

私はc++の比較的新しいユーザーですが、奇妙な問題に遭遇しています。

ToDoItem はこのスコープで宣言されていません」と表示されます。

エラーはこのクラス定義にあります。

#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を含むことになります。 ビフォー a.hはb.hをインクルードしようとしますが、インクルードガードがそれをブロックするので、コンパイラはb.hからの宣言なしにa.hを処理し、失敗します。

例えば、todoitem.h は "todolist.h" を必要としていないのにインクルードし、次に "todolist.h" は "intemmonitor.h" を必要としているのにインクルードガードにより失敗しているのです。