【问题标题】:C++ compilation error enum "does not name a type"C++ 编译错误枚举“未命名类型”
【发布时间】:2010-10-27 10:23:28
【问题描述】:

以下代码:

foo.h

#include "bar.h"
class foo{ 
public:
   enum my_enum_type { ONE, TWO, THREE }; 
   foo(); 
   ~foo() {} 
};

foo.cpp

foo::foo()
{
   int i = bar::MY_DEFINE;
}

bar.h

#include "foo.h"
class bar{
public:
   static const int MY_DEFINE = 10;
   foo::my_enum_type var;
   bar() {};
   ~bar() {};
};

使 g++ 编译器抱怨 my_enum_type “没有命名类型”。 为什么 ? 所有标头都有多个包含定义(为清楚起见,此处未显示)。

谢谢

【问题讨论】:

  • 这应该可以正常工作...
  • 你如何使用这些课程?你这里还没有源文件。你能分享一下你是如何使用这些类的吗?
  • 谢谢大家,你们让我意识到问题不在于语法,而在于我如何使用这些类。 foo.h 中有一个#include "bar.h",我用前向声明替换它,现在一切都很好!
  • @Rémy:所以,您提供的代码不是您遇到问题的代码。道德:为了得到有用的答案,呈现实际的代码。 :-) 干杯,
  • 现在你有了循环包含:foo.h 包含 bar.h,bar.h 包含 foo.h。你不需要第一个。请给出一个可以实际重现您所看到的错误的小示例。

标签: c++ enums types


【解决方案1】:

您必须移除循环依赖,因此您需要将 foo.cpp 和 foo.h 视为不同的单位。

  • bar 类定义必须看到 foo::my_enum_type 所以可能 bar.h 包括 foo.h 是必要的。

  • foo 类定义不使用任何 bar,所以 foo.h 不需要包含 bar.h

  • foo.cpp 确实需要查看 MY_DEFINE 的 bar,因此 foo.cpp 应该包含 bar.h。这实际上也会自动引入 foo.h,但您可能希望将其包含在 foo.cpp 中,以防您稍后删除依赖项。

大概你的标题有多个包含保护。

【讨论】:

  • 我不知道您必须分别考虑 .h 和 .cpp 依赖项。我认为在 .cpp 中包含多个 .h 是不好的设计。我可能错了,你的回答解决了我的问题。谢谢:)
【解决方案2】:

问题:

  • 没有多重包含保护
  • 循环包含
  • 循环包含导致声明前使用类型

C 预处理器正在处理的 foo.h 看起来像无限的空字符串序列。

通过多重包含保护 foo.h 被预处理为:

> cpp foo.h
class bar{ // preprocessed from #include "bar.h"
public:
   static const int MY_DEFINE = 10;
   foo::my_enum_type var;
   bar() {};
   ~bar() {};
};
// end of #include "bar.h"
class foo{ 
public:
   enum my_enum_type { ONE, TWO, THREE }; 
   foo(); 
   ~foo() {} 
};

这显然不是一个有效的 C++ 代码 - foo 在没有事先声明的情况下在 bar 主体中使用。 C++ 与 Java 不同,需要在使用前声明类型。

  • 使用多重包含保护。根据您的平台,这些可能是 #ifndef 宏或 #pragma once 指令
  • 从 foo.h 中删除 bar.h。
  • 在需要的地方放置前向声明(在您的情况下,bar 可能会在 foo.h 中前向声明,但您的示例并未显示出这种情况的必要性)。
  • 将尽可能多的实现移至 *.cpp 文件。

如果这些建议无法解决问题,请使用PIMPL idiom

简而言之 - 只需从 foo.h 中删除 #include "bar.h" 指令

【讨论】:

  • 我的标题有多重包含保护。如果我从 foo.h 中删除 bar.h,则 foo.cpp 不能再使用 bar::MY_DEFINE('bar' 尚未声明)。
  • 错了。如果您在 foo.cpp 本身中包含 bar.h,则 foo.cpp 仍然可以使用 bar。
  • 是的,那是我不知道的;)
【解决方案3】:
foo()
{
   int i = bar::MY_DEFINE;
}

应该是

foo::foo()
{
   //...
}

还要注意

static const int MY_DEFINE = 10;

仍然是一个声明,尽管它有一个初始化器。在 bar.cpp 你应该有以下行

const int bar::MY_DEFINE;

你也不能包含来自 foo.h 的 bar.h 和来自 bar.h 的 foo.h...这在物理上是不可能的 :)

【讨论】:

    猜你喜欢
    • 2012-01-07
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    相关资源
    最近更新 更多