したがって、別のクラスに含まれるクラスがあり、「error: '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を使用しています。
あなたは、あなたが示しているコードが実際に問題を抱えているコンパイラエラーを生成しないと言っているようです。したがって、推測することしかできません。以下にいくつかの可能性を示します。
ヘッダーファイル/クラスで循環依存関係の結果として同じエラーメッセージが表示されました。
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つのファイルがあり、gcc * .cppを実行している場合、この問題が発生します。これは、コンパイルされる個々のオブジェクトファイルだけでなく、gccインスタンス全体に対して#defineが定義されるために発生します。
例.
File1
#ifndef FILE1_HPP
#define FILE1_HPP 1
....
#endif
次に、それを参照する2つの個別のファイル。
#include <file1.hpp>
同時にコンパイルしようとすると、FILE1_HPPがすでに定義されているため、cppファイルの1つが失敗します(そのcppファイルではヘッダーファイルが無視されるため)。
gcc -Wall *.cpp
答えは、#ifndefを削除するか、各ファイルを独自のオブジェクトファイルにコンパイルしてから、メインアプリケーションにリンクすることです。
同様の問題を経験しましたが、その理由を見つけるのに時間がかかりました。
あなたの場合、他のいくつかのヘッダーファイルでPROBLEMCLASS_Hを定義できます。その結果、cppファイルはヘッダーファイルの定義をスキップします。つまり、#include "problemclass.h"
行はスキップされます。
私の場合、LinuxでMingW64を使用しています。 IO.hというヘッダーファイルがあるとします。
// IO.h
#ifndef _IO_H_
#define _IO_H_
class A{
...
};
#endif
私のmain.cppファイルで:
// main.cpp
#include <unistd.h>
#include "IO.h"
int main(int argc, char** argv) {
//...
}
Cppファイルは無害に見えます。ただし、unistd.h
が含まれている場合、MingWが提供する/usr/i686-w64-mingw32.static/include/io.h
が密かに含まれており、このio.h
は次のようになります。
// io.h
#ifndef _IO_H_
#define _IO_H_
...
#endif /* End _IO_H_ */
unistd.h
を含めると、MingWからio.h
が含まれることになります。これにより、独自のIO.hが非表示になります。それはあなたと同じような問題だと思います。
インクルードの順序を切り替えると(IO.hの後に#include <unistd.h>
を置く)、プログラムがコンパイルされます。しかし、これは良い提案ではありません。 _IO_H_を使用して独自のIO.hを保護しないことをお勧めします。
PROBLEMCLASS_H
がどのように/なぜ含まれているかを理解するために、@ greatwolfに同意します。g++ -E
を使用してプリプロセッサ出力を出力し、手動で調べることができます。 PROBLEMCLASS_H
の前にどのファイルが含まれているか、またそれらが含まれている順序を確認してください。それがあなたの問題の解決に役立つことを願っています。
この投稿を見てこのエラーが発生した人には、関数名の前にクラス指定子を追加するのを忘れたときに頻繁に起こることを指摘したいと思います。そのクラス関数はクラスのヘッダーでプライベートに定義されたものを使用します。
例えば:
ヘッダ
class SomeClass
{
public:
void SomeFunc();
private:
typedef int SomeType_t;
};
ソース(エラーをスローしますSomeType_tが定義されていません)
void SomeFunc()
{
SomeType_t dummy = 0;
}
ソース(固定)
void SomeClass::SomeFunc()
{
SomeType_t dummy = 0;
}
これは馬鹿げていますが、本当に簡単な間違いであり、机に頭をぶつけてから3つの脳震盪を与えてから見るまで見ないでください。
あなたが提示したものに基づいてコンパイルエラーを引き起こすと私が考えることができる唯一のものは、PROBLEMCLASS_H
ヘッダーファイルの外部で何らかの形で再定義されました。例えば:
//main.cpp
#define PROBLEMCLASS_H
#include "aclass.h"
int main() {}
あなたが試すことができる一つのアイデアは、 'proclassmclass.h'を 'aclass.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」拡張子)を開き、実際に何が起こっているのかを調べます。これは、「インクルード」が多数あり、予測が難しい場合に特に便利です。
私は同じ問題を抱えていて、私が間違っていたことを発見しました。あなたの例に従って、AClassにProblemClassを含めたので、問題が発生しました。