所以我有一个类包含在另一个类中,它继续抛出“错误:'ProblemClass'形式的编译错误。文件是这样设置的:
#ifndef PROBLEMCLASS_H
#define PROBLEMCLASS_H
#include <iostream>
#include <cmath>
class ProblemClass
{
public:
virtual void Init() = 0;
};
#endif
并且发生错误的类看起来像这样:
#ifndef ACLASS_H
#define ACLASS_H
#include "problemclass.h"
class AClass : public Base
{
public:
void DoSomething(ProblemClass* problem);
};
#endif
编译错误发生在void Dosomething();
我知道这里的代码不足以解决问题。我一直无法创建一个可以重现它的最小例子。所以我的问题更为笼统;什么样的事情可能会导致这种情况?有什么特别的东西我应该寻找,或者我应该追踪一些调查线来跟踪它?
此代码在项目的几乎完全相同的版本中编译良好。
无论多么模糊,都会非常感谢任何形式的帮助。我在win 7 64位中使用了mingw4.4.1的代码块10.05。
答案 0 :(得分:85)
您似乎在说,您显示的代码实际上并不会产生您遇到问题的编译器错误。所以我们只能猜测。以下是一些可能性:
答案 1 :(得分:28)
我的头文件/类中的循环依赖导致了同样的错误消息:
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:
#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
使用: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’
答案 2 :(得分:2)
请发布您用于编译的命令。我已经看到过这个问题,如果你有2个单独的文件,包含相同的标题,你正在做一个gcc * .cpp。发生这种情况是因为#define是为整个gcc实例定义的,而不仅仅是为每个正在编译的单个目标文件定义的。
实施例。
File1中
#ifndef FILE1_HPP
#define FILE1_HPP 1
....
#endif
然后是两个引用它的独立文件。
#include <file1.hpp>
尝试同时编译所有cpp文件会导致其中一个cpp文件失败,因为已经定义了FILE1_HPP(导致该cpp文件忽略头文件)。
gcc -Wall *.cpp
答案是删除#ifndef,或者将每个文件编译成自己的目标文件,然后将它们链接到主应用程序中。
答案 3 :(得分:1)
我能想到的唯一一件事会导致基于你所呈现的编译错误,如果PROBLEMCLASS_H
以某种方式在头文件之外被重新定义。例如:
//main.cpp
#define PROBLEMCLASS_H
#include "aclass.h"
int main() {}
您可以尝试的一个想法是不在'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
可用于帮助追踪此标头问题的另一种技术是预处理有问题的“.cpp”编译单元。打开预处理的输出文件(通常是'.i'扩展名)并检查实际发生的情况。这很方便,特别是如果'包括'很多并且很难预测。
答案 4 :(得分:1)
我遇到了类似的问题,我花了一段时间才找出原因。
在您的情况下,您可以在其他一些头文件中定义PROBLEMCLASS_H。
结果是你的cpp文件将跳过头文件中的定义。换句话说,跳过行 ((TextView) jobCategory.getSelectedView().findViewById(R.id.firstName)).setError("Field Required");
。
就我而言,我在Linux下使用MingW64。假设我有一个头文件IO.h:
#include "problemclass.h"
在我的main.cpp文件中:
// IO.h
#ifndef _IO_H_
#define _IO_H_
class A{
...
};
#endif
cpp文件看起来很无辜。但是,当包含// main.cpp
#include <unistd.h>
#include "IO.h"
int main(int argc, char** argv) {
//...
}
时,它会秘密地包含MingW提供的unistd.h
,并且此/usr/i686-w64-mingw32.static/include/io.h
看起来像:
io.h
现在您可以看到包含// io.h
#ifndef _IO_H_
#define _IO_H_
...
#endif /* End _IO_H_ */
将导致MingW包含unistd.h
,这将隐藏我自己的IO.h.我想这与你的问题类似。
如果切换包含的顺序(在IO.h之后放置io.h
),程序将编译。但这不是一个好建议。我建议您不要使用_IO_H_来保护自己的IO.h。
要了解如何/为什么包含#include <unistd.h>
,我同意@greatwolf,您可以使用PROBLEMCLASS_H
输出预处理器输出并手动检查它。检查g++ -E
之前包含的文件以及包含的顺序。我希望这可以帮助你解决问题。
答案 5 :(得分:1)
对于看到这篇文章并且出现此错误的任何人,我想指出,当我忘记在函数名称之前添加类说明符时,这经常发生在我身上,其中该类函数使用在类的标头中私有定义的东西。
EG:
标题
ORDER BY
来源(将抛出错误 SomeType_t未定义)
class SomeClass
{
public:
void SomeFunc();
private:
typedef int SomeType_t;
};
来源(固定)
void SomeFunc()
{
SomeType_t dummy = 0;
}
这是一个愚蠢的,但很容易犯的错误,直到你用自己的头撞在桌子上给自己三次脑震荡后才能看到。
答案 6 :(得分:0)
我遇到了同样的问题,并且发现自己做错了什么:按照您的示例,我在AClass中包含了ProblemClass,因此引起了问题。
答案 7 :(得分:0)
转发声明'ProblemClass'应该做的事情。前向声明对于解决引发链接程序/编译器错误的循环包含是必需的。
如果遇到此类问题,请遍历标题并在可能的情况下进行正向声明,这是一个好习惯。
答案 8 :(得分:0)
遇到了同样的问题, A.h 包含在 B1.h 和 B2.h 中 B2.h 也包含在 B2.cpp 中
使用 #pragma once 在A.h班 这解决了问题。
答案 9 :(得分:-1)
代码:
#include <iostream>
#include <conio.h>
int main(){
char c = ' ';
std::string pw;
while (c!=13){ // c = 13 is 'Enter' key.
c = getch();
if (c!=13){
pw +=c;
std::cout << "*";
}
}
std::cout <<"\nPassword is :" << pw;
}
输出:
***********
Password is :password123