以下代码:
foo.h
#include "bar.h"
class foo{
public:
enum my_enum_type { ONE, TWO, THREE };
foo();
~foo() {}
};
Run Code Online (Sandbox Code Playgroud)
文件
foo::foo()
{
int i = bar::MY_DEFINE;
}
Run Code Online (Sandbox Code Playgroud)
酒吧.h
#include "foo.h"
class bar{
public:
static const int MY_DEFINE = 10;
foo::my_enum_type var;
bar() {};
~bar() {};
};
Run Code Online (Sandbox Code Playgroud)
使 g++ 编译器抱怨 my_enum_type “未命名类型”。为什么 ?所有标题都有多个包含定义(为清楚起见,此处未显示)。
谢谢
问题:
由 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() {}
};
Run Code Online (Sandbox Code Playgroud)
这显然不是有效的 C++ 代码 - foo 在没有事先声明的情况下用于 bar body 中。与 Java 不同,C++ 要求在使用前声明类型。
#ifndef宏或#pragma once指令bar可能会在 foo.h 中进行前向声明,但您的示例并未显示这样做的必要性)。如果这些建议无法解决这种情况,请使用PIMPL idiom。
简而言之 - 只需#include "bar.h"从 foo.h 中删除指令
您必须删除循环依赖,因此您需要为此目的将 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 中,以防您稍后删除依赖项。
大概你的标题有多个包含守卫。