7

以下で説明するクラス構造を持つ単純なインタープリターを C++ で書き始めましたが、ヘッダーが苦労していたので、やめて Java で書き直しました。C++ では明らかに許可されていない基本的な構造を次に示します。

main.cppには main 関数が含まれており、 printer.hを呼び出すことができるクラスのヘッダーが含まれています(その単一の void メソッドはprinter.cppに実装されています)。ここで、同一の他の 2 つのクラスを想像してください。どちらも を呼び出したいので、それぞれにprinter.hPrinter::write_something();を含めました。ここに私の最初の質問があります#include <iostream>ヘッダーは一度?(まあ、同じファイルにある限り、おそらく私のものでも同じことができると思います。しかし、間違っているかもしれません。)宣言と実装/定義の違いは理解していますが、そのコードは私にクラスの再定義エラー。理由がわかりません。そして、これが私の心を吹き飛ばすことです (そして、おそらく私がこれを理解していない理由を示しています): main.cppの先頭にprinter.hを含めて、他の 2 つのクラスのクラスを使用することはできません。2つのクラス (ヘッダー) のいずれかに問題なくprinter.hをインクルードできることはわかっていますが、 main.cppにクラスをインクルードする前にそれをインクルードするのとなぜこれが異なるのかわかりません(そうすると、私にはクラスが見つからないというエラーがあります)。

うんざりしたとき、私が使っていた OOP はとにかくかなり強引だったので、C に移行することを考えましたが、すべてを 1 つのファイルに記述しないと同じ問題に遭遇します。C++ を知っているのに、コンパイルの問題で正しく使えないというのは、もどかしいものです。

これを解決していただければ幸いです。ありがとう!

4

3 に答える 3

9

100 万回 #include できるのに、ヘッダーを 1 回しかインクルードできないのはなぜですか?

おそらく、ヘッダーにインクルード ガードがないためです。

// printer.h file
#ifndef PRINTER_H_
#define PRINTER_H_

 // printer.h code goes here

#endif

2 つの異なるヘッダーが同じヘッダーを持つ可能性を最小限に抑えるために、インクルード ガード定義に長い名前を選択することがベスト プラクティスであることに注意してください。

于 2013-01-23T17:04:03.020 に答える
4

ほとんどのヘッダー ファイルはインクルード ガードでラップする必要があります。

#ifndef MY_UNIQUE_INCLUDE_NAME_H
#define MY_UNIQUE_INCLUDE_NAME_H

// All content here.

#endif

このようにして、コンパイラは、翻訳単位ごとに 1 回だけヘッダーの内容を確認します。

于 2013-01-23T17:04:43.587 に答える
0

C/C++ コンパイルは、コンパイル/変換単位に分割され、オブジェクト ファイルが生成されます。(.o、.obj)

翻訳単位の定義はこちら

C/C++ ファイル内の #include ディレクティブは、同じファイル内の単純な再帰的なコピー アンド ペーストと直接同等の結果になります。実験として試すことができます。

そのため、同じ翻訳単位に同じヘッダーが 2 回含まれている場合、コンパイラは、一部のエンティティが複数回定義されていることを認識します。これは、同じファイルに記述した場合と同様です。エラー出力はまったく同じです。

この言語には複数のインクルードを防止する組み込みの保護がないため、C/C++ ヘッダーごとにインクルード ガードまたは特定の #pragma ボイラープレートを記述する必要があります。

于 2013-01-23T19:17:07.543 に答える