C++ 错误:尽管包含头文件,但尚未声明类,并且代码在其他地方编译得很好
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6554492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
error: Class has not been declared despite header inclusion, and the code compiling fine elsewhere
提问by gj5
So I have a class included in another class that keeps throwing a compile error of the form "error: 'ProblemClass' has not been declared. The files are set up thusly:
所以我有一个包含在另一个类中的类,它不断抛出形式为“错误:'问题类'尚未声明的编译错误。文件是这样设置的:
#ifndef PROBLEMCLASS_H
#define PROBLEMCLASS_H
#include <iostream>
#include <cmath>
class ProblemClass
{
public:
virtual void Init() = 0;
};
#endif
and the class where the error occurs looks like this:
发生错误的类如下所示:
#ifndef ACLASS_H
#define ACLASS_H
#include "problemclass.h"
class AClass : public Base
{
public:
void DoSomething(ProblemClass* problem);
};
#endif
The compile error occurs at void Dosomething();
编译错误发生在 void Dosomething();
I'm aware the code here isn't enough to solve the problem. I've been unable to create a minimal example that can reproduce it. So my question is much more general; what sort of things might cause this? Is there anything in particular I should look for, or some line of enquiry I should be following to track it down?
我知道这里的代码不足以解决问题。我一直无法创建一个可以重现它的最小示例。所以我的问题要笼统得多;什么样的事情可能会导致这种情况?有什么我应该特别寻找的东西,或者我应该遵循一些查询来追踪它吗?
This code compiles fine in an almost identical version of the project.
这段代码在几乎相同的项目版本中编译得很好。
Help of any sort would be greatly appreciated, no matter how vague. I'm using codeblocks 10.05 with mingw4.4.1 in win 7 64 bit.
无论多么模糊,任何形式的帮助都将不胜感激。我在 win 7 64 位中使用代码块 10.05 和 mingw4.4.1。
回答by Bjarke H. Roune
You seem to be saying that the code you are showing doesn't actually produce the compiler error that you are having a problem with. So we can only guess. Here are some possibilities:
您似乎在说您显示的代码实际上并没有产生您遇到问题的编译器错误。所以我们只能猜测。这里有一些可能性:
回答by Manik
I've had that same error message as a result of a circular dependencyin my header files / classes:
由于头文件/类中的循环依赖,我收到了同样的错误消息:
foo.hpp:
foo.hpp:
#ifndef FOO_HPP
#define FOO_HPP
#include <stdio.h>
#include "bar.hpp" // <-- here
class Foo {
public:
int value = 0;
void do_foo(Bar myBar) {
printf("foo + %d\n", myBar.value);
}
};
#endif //FOO_HPP
bar.hpp:
栏.hpp:
#ifndef BAR_HPP
#define BAR_HPP
#include <stdio.h>
#include "foo.hpp" // <-- and here
class Bar {
public:
int value = 1;
void do_bar(Foo myFoo) {
printf("bar = %d \n", myFoo.value);
}
};
#endif //BAR_HPP
Compiling with: g++ -std=c++11 foo.hpp -o foo
resulted in the following output:
编译:g++ -std=c++11 foo.hpp -o foo
导致以下输出:
In file included from foo.hpp:5:0:
bar.hpp:11:15: error: ‘Foo' has not been declared
bar.hpp: In member function ‘void Bar::do_bar(int)':
bar.hpp:12:32: error: request for member ‘value' in ‘myFoo', which is of non-class type ‘int'
回答by Suroot
Please post the command you are using for compilation. I've seen this issue if you have 2 separate files that include the same header and you are doing a gcc *.cpp. This happens because the #define gets defined for the entire gcc instance and not just for each individual object file being compiled.
请发布您用于编译的命令。如果您有 2 个包含相同标头的单独文件并且您正在执行 gcc *.cpp,我就会看到这个问题。发生这种情况是因为 #define 是为整个 gcc 实例定义的,而不仅仅是为正在编译的每个单独的目标文件。
Ex.
前任。
File1
文件1
#ifndef FILE1_HPP
#define FILE1_HPP 1
....
#endif
Then two separate files that reference it.
然后是引用它的两个单独的文件。
#include <file1.hpp>
Trying to compile all at the same time will cause one of the cpp files to fail since FILE1_HPP was already defined (causing the header file to be ignored for that cpp file).
尝试同时编译所有文件将导致其中一个 cpp 文件失败,因为 FILE1_HPP 已经定义(导致该 cpp 文件的头文件被忽略)。
gcc -Wall *.cpp
Answer is either remove the #ifndef, or to compile each file into its own object files and then link them into your main application.
答案是删除#ifndef,或者将每个文件编译成它自己的目标文件,然后将它们链接到您的主应用程序中。
回答by greatwolf
The only thing I could think of that would cause the compile error based on what you have presented is if PROBLEMCLASS_H
somehow got redefined outside the header file. Like for example:
根据您提供的内容,我唯一能想到的会导致编译错误的是,如果PROBLEMCLASS_H
以某种方式在头文件之外重新定义。例如:
//main.cpp
#define PROBLEMCLASS_H
#include "aclass.h"
int main() {}
One idea you can try is to not include 'problemclass.h' in 'aclass.h' but just do a forward declare of ProblemClass
instead. For this to work you have to make sure AClass
's definition only contains references or pointers to ProblemClass
-- you don't want the compiler to try and take the size of ProblemClass
which would need its full definition.
您可以尝试的一个想法是不要在 'aclass.h' 中包含 'problemclass.h',而是只做一个前向声明ProblemClass
。为此,您必须确保AClass
的定义仅包含指向的引用或指针ProblemClass
——您不希望编译器尝试获取ProblemClass
需要其完整定义的大小。
//aclass.h
#ifndef ACLASS_H
#define ACLASS_H
class ProblemClass;
class AClass : public Base
{
public:
void DoSomething(ProblemClass* problem);
};
#endif
Another technique you can use to help track down this header problem is to just preprocess the problematic '.cpp' compilation unit. Open up the preprocessed output file(usually '.i' extension) and inspect what is actually happening. This is handy especially if the 'includes' are numerous and hard to predict.
您可以用来帮助追踪此头文件问题的另一种技术是对有问题的“.cpp”编译单元进行预处理。打开预处理的输出文件(通常是“.i”扩展名)并检查实际发生的情况。这很方便,特别是如果“包含”数量众多且难以预测。
回答by zhanxw
I have experienced a similar problem and it took me a while to find out why.
我遇到了类似的问题,我花了一段时间才找出原因。
In your case, you may define PROBLEMCLASS_H in some other header files.
The consequence is your cpp file will skip the definition in the header file. In other words, the line #include "problemclass.h"
is skipped.
在您的情况下,您可以在其他一些头文件中定义 PROBLEMCLASS_H。结果是您的 cpp 文件将跳过头文件中的定义。换句话说,该行#include "problemclass.h"
被跳过。
In my case, I am using MingW64 under Linux. Say I have a header file IO.h:
就我而言,我在 Linux 下使用 MingW64。假设我有一个头文件 IO.h:
// IO.h
#ifndef _IO_H_
#define _IO_H_
class A{
...
};
#endif
In my main.cpp file:
在我的 main.cpp 文件中:
// main.cpp
#include <unistd.h>
#include "IO.h"
int main(int argc, char** argv) {
//...
}
The cpp file looks innocent. However, when unistd.h
is included, it secretly includes /usr/i686-w64-mingw32.static/include/io.h
supplied by MingW, and this io.h
looks like:
cpp 文件看起来很无辜。但是,当unistd.h
被包含时,它会秘密包含/usr/i686-w64-mingw32.static/include/io.h
由 MingW 提供的,这io.h
看起来像:
// io.h
#ifndef _IO_H_
#define _IO_H_
...
#endif /* End _IO_H_ */
Now you can see that inclusion of unistd.h
will lead to the inclusion io.h
from MingW, and that will hide my own IO.h. I guess that's a similar problem like yours.
现在你可以看到包含unistd.h
将导致io.h
来自 MingW的包含,这将隐藏我自己的 IO.h。我想这和你的问题类似。
If you switch the order of includes (put #include <unistd.h>
after IO.h), the program compiles. But this is not a good suggestion. I recommend that you don't use _IO_H_ to guard your own IO.h.
如果您切换包含的顺序(放在#include <unistd.h>
IO.h 之后),程序就会编译。但这不是一个好建议。我建议你不要用_IO_H_来守护你自己的IO.h。
To understand how/why your PROBLEMCLASS_H
is included, I agree with @greatwolf, you can use g++ -E
to output the preprocessor output and manually examine it. Check what files are included before your PROBLEMCLASS_H
and in what order they are included. I hope that can help solve your problem.
要了解如何/为什么PROBLEMCLASS_H
包含您的内容,我同意@greatwolf,您可以使用g++ -E
输出预处理器输出并手动检查它。检查在您之前包含哪些文件PROBLEMCLASS_H
以及它们包含的顺序。我希望这可以帮助解决您的问题。
回答by L-S
To anyone seeing this post and having this error, I want to point out that this frequently happens to me when I forget to add the class specifier before a function name, wherein that class function uses something privately defined in the class's header.
对于看到这篇文章并遇到此错误的任何人,我想指出,当我忘记在函数名称之前添加类说明符时,这种情况经常发生在我身上,其中该类函数使用类标题中私有定义的某些内容。
EG:
例如:
Header
标题
class SomeClass
{
public:
void SomeFunc();
private:
typedef int SomeType_t;
};
Source (Will throw error SomeType_t is not defined)
来源(会抛出错误SomeType_t is not defined)
void SomeFunc()
{
SomeType_t dummy = 0;
}
Source (Fixed)
来源(固定)
void SomeClass::SomeFunc()
{
SomeType_t dummy = 0;
}
This is a dumb, but really easy mistake to make and not see until after you have given yourself three concussions from hitting your head against the desk.
这是一个愚蠢但非常容易犯的错误,直到你的头撞在桌子上给自己造成了三个脑震荡之后才能看到。
回答by Raul Luna
I had the same problem and I've discovered what I was doing wrong: following your example, I've included ProblemClass in AClass, thus causing the problem.
我遇到了同样的问题,我发现我做错了什么:按照你的例子,我在 AClass 中包含了 ProblemClass,从而导致了问题。