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

理论上,g++ 应该在包含它的类之前编译一个类。

g++ 应该能够以它认为合适的任何顺序编译您的源文件。它在源代码中包含标题的顺序由#include语句的顺序设置。

最可能的情况是类名是room,而不是Room。下一个可能是名称除了 之外是其他东西Room。不太可能是它位于根名称空间以外的名称空间中。

编辑:好的,如果不是这些,请确保room.h包含的内容是您的room.h,而不是其他room.h的。没有什么比编辑错误的文件副本更能浪费你的一天了。

编辑2:我假设您的头文件具有通常的包含一次结构:

#ifndef schedule_h
#define schedule_h

// header file code goes here.

#endif

...为了简洁起见,您省略了它。

编辑3:我刚刚将您提供的代码复制到一个新目录,并创建了一个day.h包含内容的虚拟文件:

typedef int Day;

然后我用来g++ -c -o schedule.o schedule.cpp构建它并且没有错误。因此,错误是我们没有看到的。

编辑 4:好的,健全性检查时间。查看顶部room.h并确保上面写着

#ifndef room_h

并不是

#ifdef room_h
于 2010-04-26T16:30:37.380 回答
0

我无法从您的 schedule.h/.cpp 帖子中看出,但看起来您可能在 schedule.cpp 中有 #include "room.h",但您的 schedule.h 正在使用课堂房间。如果是这种情况,#include "room.h" 应该在 schedule.h 中。

或者您可以在 schedule.h 中使用前向声明。

于 2010-04-26T16:48:19.497 回答
0

Room.cpp 是什么样的?

另外..我从来没有遇到过任何问题,但是也许您忘记在头文件的底部多加一行?

于 2010-04-26T17:56:47.613 回答