我遇到的问题是我完全无法理解或非常奇怪的问题。这可能是第一个,但我整个下午都在谷歌上搜索没有成功,所以这里有...
我有一个名为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();
};
答案 0 :(得分: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
。
答案 1 :(得分:1)
这可能无关紧要,但我看到你的标题中没有包含警戒。无所谓,但只是为了涵盖任何角度......
答案 2 :(得分: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
答案 3 :(得分:0)
我无法从你的schedule.h / .cpp文章中看出来,但看起来你可能在schedule.cpp中有#include“room.h”,但你的schedule.h正在使用class Room。如果是这种情况,#include“room.h”应该在schedule.h中。
或者您可以在schedule.h中使用前向声明。
答案 4 :(得分:0)
Room.cpp是什么样的?
另外..我从来没有遇到任何问题,但也许你忘了在头文件的底部多加一行?