C ++编译错误枚举“没有命名类型”

时间:2010-10-27 10:23:29

标签: c++ enums types

以下代码:

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“没有命名类型”。 为什么? 所有标题都有多个包含定义(为清楚起见,此处未显示)。

由于

3 个答案:

答案 0 :(得分:4)

问题:

  • 没有多重包含保护
  • 循环包含
  • 在声明由循环包含引起之前的类型使用

由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体中而没有事先声明。与Java不同,C ++需要在使用之前声明类型。

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

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

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

答案 1 :(得分:2)

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

应该是

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

另请注意

static const int MY_DEFINE = 10;

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

const int bar::MY_DEFINE;

此外,您不能在f.h中包含bar.h,也不能在bar.h中包含foo.h ......这在物理上是不可能的:)

答案 2 :(得分:2)

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

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

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

  • foo.cpp确实需要查看MY_DEFINE的栏,所以foo.cpp应该包含bar.h.这实际上也会自动引入foo.h,但你可能希望在foo.cpp中包含它,以防你以后删除依赖。

据推测,你的标题有多个包含警戒。