1

こんばんは :)

私はg ++とメイクファイルをいじっています。私はこの点に到達しました:

foo.h:

#ifndef _FOO_H_
#define _FOO_H_

#include "bar.h"

class foo {
private:
    bar something;
public:
    bool start();
    bool stop();
};

#endif // _FOO_H_

Foo.h は最終的にメインの cpp ファイルに含まれるので、start/stop を呼び出して動作を設定できます。

void somewhere() {
    foo* hihi = new foo;
    hihi->start();
    delete hihi;
}

それから bar.h があります:

#ifndef _BAR_H_
#define _BAR_H_

class bar {

};

#endif // _BAR_H_


ただし、g ++は気に入らないようです:

g++  (some_flags) -c main.cpp
In file included from main.cpp:2:
foo.h:8: error: ‘bar’ does not name a type

私はmakefileを使用しており、次のような組み合わせを試しました:

main.o: main.cpp foo.h bar.h

ここに bar.h を追加する必要はないと思いますが、foo.h に含めるだけで十分ではないでしょうか?

明確にするために、これは大まかに現在設定されている方法です(はい、これはより効率的な方法で実行できることを知っています):

main.o: main.cpp foo.h
    $(CC) $(CFLAGS) -c main.cpp

foo.o: foo.h foo.cpp
    $(CC) $(CFLAGS) -c foo.cpp

bar.o: bar.h bar.cpp
    $(CC) $(CFLAGS) -c bar.cpp

どうしたの?g ++について欠けているものであり、ヘッダーインクルードの処理方法が含まれていると思います。正しい方向に向けてください!

編集 - 解決策を見つけました:

どっ!私は今、ばかげていると感じています。boost::asio をいじっていましたが、これをヘッダーのどこかに残していたことを忘れていました: using boost::asio::ip::tcp;

boost::asio::ip::tcp::bar 関数があるとしましょう:D

ああ、とにかくありがとう!

4

4 に答える 4

2

すべてを再確認してください。にインクルードbar.hした場合foo.h、コンパイラはエラーを発生させません。foo.hからを含めますbar.hか?これを行うと、ヘッダー間の循環依存が発生し、そのようなバグが発生するため、これを行わないでください。

また、ヘッダー ガードのスペルもチェックします。これは、煩わしさの一般的な原因となる可能性があります。

#ifdef _BAR_H_ // OOPS! we wanted #ifndef
#define _BAR_H_

class bar {

};

#endif // _BAR_H_

さらに、ヘッダー ガード マクロ名の前にアンダースコアを付けることは避けてください。これらの名前は、コンパイラに予約されています。それを呼び出すINCLUDED_BAR_Hか、BAR_H_代わりに呼び出します。

于 2009-03-22T04:23:22.357 に答える
2

boost::asio をいじっていましたが、これをヘッダーのどこかに残していたことを忘れていました: using boost::asio::ip::tcp;

boost::asio::ip::tcp::bar 関数があるとしましょう

Dan Saks は、冗長に思えるかもしれませんが、クラス名を型定義する必要があるいくつかの理由を説明しています。

さて、クラスを型定義すると、おそらく問題を少し簡単に見つけるのに役立つという実際の状況に遭遇しました。

 class bar {
 // ...
 };
 typedef class bar bar;

bar()すでに宣言されているという名前の関数がある場合、このより意味のあるメッセージを生成します。

In file included from C:\temp\foo.h:4,
                 from C:\temp\test.cpp:4:
C:\temp\bar.h:7: error: `typedef class bar bar' redeclared as different kind of symbol
C:\temp\test.cpp:1: error: previous declaration of `void bar(int)'
C:\temp\bar.h:7: error: declaration of `typedef class bar bar'
于 2009-03-22T04:48:25.510 に答える
1

Tommy Hui と litb はすでに 2 つの考えられる原因を指摘しています。ここでは、役立つと思われる背景情報をいくつか紹介します。

まず、これはメイクファイルとは関係ありません。makefile は単に g++ を呼び出す便利なものであり、それ以上のものではありません。

ヘッダー ファイルを使用するこのようなものは、特に循環依存関係に入ると、最初は理解するのが少し難しい場合があります。次の 3 つのことを理解するのに非常に役立ちました。

  • A#includeは、その時点で含まれているファイルの内容を挿入する、コピー/貼り付け操作にすぎません。
  • 使用する前にすべてを宣言する必要があります。class bar;場合によっては、循環依存関係が発生した場合、別のヘッダーでクラス (例: ) を事前宣言する必要がある場合があります。
  • 使用時に、型の存在以外の情報が必要な場合は、型の定義も必要です。これは、例えば、そのタイプのオブジェクトのメソッドの呼び出しだけでなく、そのタイプのフィールドを含める場合にも当てはまります! (ただし、ポインターはすべて同じサイズであるため、その型のオブジェクトへのポインターではありません。)
于 2009-03-22T04:25:03.350 に答える
0

main.cpp では、ファイルの先頭に次の行を追加する必要があります。

#include "foo.h"
于 2009-03-22T04:17:23.447 に答える