1

私は完全に理解できなかったか、非常に奇妙な問題を抱えています。それはおそらく最初のものですが、私は午後全体をグーグルで過ごしましたが成功しなかったので、ここに行きます...

私はScheduleというクラスを持っています。これは、メンバーとしてRoomのベクトルを持っています。ただし、cmakeを使用して、または手動でコンパイルすると、次のようになります。

In file included from schedule.cpp:1:
schedule.h:13: error: ‘Room’ was not declared in this scope
schedule.h:13: error: template argument 1 is invalid
schedule.h:13: error: template argument 2 is invalid
schedule.cpp: In constructor ‘Schedule::Schedule(int, int, int)’:
schedule.cpp:12: error: ‘Room’ was not declared in this scope
schedule.cpp:12: error: expected ‘;’ before ‘r’
schedule.cpp:13: error: request for member ‘push_back’ in ‘((Schedule*)this)->Schedule::_sched’, which is of non-class type ‘int’
schedule.cpp:13: error: ‘r’ was not declared in this scope

関連するコードは次のとおりです。

#include <vector>

#include "room.h"

class Schedule
{
  private:
    std::vector<Room> _sched; //line 13
    int _ndays;
    int _nrooms;
    int _ntslots;
  public:
    Schedule();
    ~Schedule();
    Schedule(int nrooms, int ndays, int ntslots);
};
Schedule::Schedule(int nrooms, int ndays, int ntslots):_ndays(ndays), _nrooms(nrooms),_ntslots(ntslots)
{
  for (int i=0; i<nrooms;i++)
  {
    Room r(ndays,ntslots);
    _sched.push_back(r);
  }
}

理論的には、g++はそれを含むクラスの前にクラスをコンパイルする必要があります。ここには循環依存関係はありません。すべて単純なものです。私はこれに完全に困惑しています。それは私が何かを逃しているに違いないと私に信じさせるものです。:-D

編集:以下のコメントから
の内容:room.h

#include <vector>  
#include "day.h" 

class Room 
{ 
private: 
   std::vector<Day> _days; 

public: 
   Room(); 
   Room(int ndays, int length); 
   ~Room(); 
};
4

5 に答える 5

4

いくつかの重要なコード (つまり、 の内容day.h) が省略されていても、私のサイキック デバッガーの感覚では、ヘッダー ファイルに循環依存関係があることがわかります。

// schedule.h
#include "room.h"

// room.h
#include "day.h"

// day.h
#include "schedule.h"

これは悪いです。循環依存を断ち切るには、他のファイルの具体的な実装の詳細を知る必要のないファイルを特定する必要があります。これは、前方参照を使用して行われます。たとえば、クラスの定義は、クラス定義のRoom内容を実際に知る必要がないことがわかりsizeof(Day)ます。したがって、次のように書き直すことができます。

#include <vector>
// do NOT include day.h

class Day;  // forward declaration
class Room 
{ 
private: 
   std::vector<Day> _days; 

public: 
   Room(); 
   Room(int ndays, int length); 
   ~Room(); 
};

room.hに依存しなくday.hなり、循環依存が解消されました。もちろん、実装ファイルroom.cppにはday.h.

于 2010-04-26T17:58:39.147 に答える
1

関係ないかもしれませんが、ヘッダーにインクルード ガードが表示されません。問題ではありませんが、あらゆる角度をカバーするためだけに...

于 2010-04-26T17:52:47.443 に答える
0

Room.cpp はどのようなものですか?

また..これで問題が発生したことは一度もありませんが、ヘッダー ファイルの最後に余分な行を追加するのを忘れたのではないでしょうか?

于 2010-04-26T17:56:47.613 に答える
0

schedule.h/.cpp の投稿からはわかりませんが、schedule.cpp に #include "room.h" があるようですが、あなたの schedule.h はクラス Room を利用しています。この場合、#include "room.h" は schedule.h にある必要があります。

または、schedule.h で前方宣言を使用することもできます。

于 2010-04-26T16:48:19.497 に答える
0

In theory, g++ should compile a class before the one that includes it.

g++ should be able to compile your source files in any order it sees fit. The order it includes headers into your source is set by the order of your #include statements.

The most likely case is that the class name is room, and not Room. Next likely is that the name is some other thing besides Room. Less likely is that it is in a namespace other than the root namespace.

EDIT: Okay, if it's none of those, make sure that the room.h that is being included is your room.h and not some other room.h. Nothing like editing the wrong copy of a file to waste your day.

EDIT 2: I'm assuming your header files have the usual include-once structure:

#ifndef schedule_h
#define schedule_h

// header file code goes here.

#endif

... and that you omitted it for brevity.

EDIT 3: I just copied the code you gave to a new directory, and created a dummy day.h file with the contents:

typedef int Day;

I then used g++ -c -o schedule.o schedule.cpp to build it and got no errors. Therefore the error is something we're not seeing.

Edit 4: Okay, sanity check time. Look at the top of room.h and make sure it says

#ifndef room_h

and not

#ifdef room_h
于 2010-04-26T16:30:37.380 に答える