5

我收到此编译器错误

error: 'RawLog' does not name a type

以下是相关代码:

//DataAudit.h
#ifndef DATAAUDIT_H
#define DATAAUDIT_H

class RawLog;

class DataAudit
{
...
private:
    RawLog* _createNewRawLog(); // This is the line indicated with the error
};

#endif // DATAAUDIT_H

通常,前向声明可以解决这种错误。答案表明包含循环标头可能会导致此问题。但是不使用#ifndefand#define语句不会阻止循环标题包含吗?

还有其他原因我可能会看到此错误吗?

我可以使用哪些方法来进一步推断此错误的性质?

更新:这很奇怪。我有一个Globals.h文件,如果我定义一个新enum的 in Globals.h,就会出现错误。然后,如果我注释掉enum,错误就会消失。这让我认为循环依赖已经存在了一段时间,并且添加了enum以某种方式重新排序编译单元,从而暴露了以前不存在的依赖?

4

2 回答 2

3

最后,我不确定我完全理解错误发生的原因,但这是我为解决它所做的,以及其他一些相关信息。也许这会帮助遇到这个问题的其他人。

  1. 对于我项目中的每个头文件
    1. 对于#include "..."标题中的 每个
      1. 如果 中没有对类的引用#include,请将其删除。
      2. 如果只有指向中定义的类的指针#include,则将其替换为class ...前向声明。
      3. 如果定义了类的成员实例,#include并且使用指针并在堆上分配成员是有意义的,则将成员更改为指针,并用#includeclass ....向声明替换。
  2. 浏览我的Globals.h并将任何可以从中移出的内容移到更本地化和特定的头文件中。
    1. 具体来说,删除enum已定义的 is Globals.h,并将其放在更本地化的头文件中。

在完成所有这些之后,我能够使错误消失。奇怪的是,enuminGlobals.h似乎是错误的催化剂。每当我从 中删除它时Globals.h,错误就会消失。我不明白这enum会如何导致错误,所以我认为它以某种方式间接导致了错误。我仍然无法确切地弄清楚如何或为什么,但它在使用 C++ 编码时帮助了我这个指南:

除非需要,否则不要将任何内容放在头文件中。不要在 aGlobals.h中放置任何可以放置在更本地化的文件中的东西。基本上,尽你所能减少#include指令中包含的代码量。

于 2013-08-05T16:13:29.490 回答
3

#ifndef头保护不会阻止循环依赖。它只是防止在单个文件中多次包含相同的标题。

对我来说看起来像是一个循环依赖。这意味着您#include在 DataAudit.h 中有一个标题,即#include直接或间接的 DataAudit.h。

于 2013-08-02T22:25:18.513 回答