web-dev-qa-db-ja.com

ヘッダーファイルを含める方法

ヘッダーファイルをインポートする方法は重要ですか?二重引用符と矢印の使用を見てきました。

#include <stdlib.h>
#include "Some_Header.h"

彼らが特定の方法で同様に資本化されているかどうかは重要ですか?これをいろいろ試してみるとどちらも問題ないようですが、チュートリアルがそのようにやっているのには理由があるに違いないと思います。

もう1つの質問は、(Javaここから)、それが定義されたファイルの外部のクラスにアクセスするにはどうすればよいですか?)たとえば、one.cppとtwo.cppがあります。

One.cppで:

class Something {
    ...

Two.cppで:

class SomethingElse {
    Something *example;
    ...

あれ? Javaでは、クラス名の前に「public」を付けるだけです。C++では、クラスのラングリングは少し難しいようです。

13
Andrew Rabon

#includeディレクティブの山括弧は、検索パスが「システム」インクルードディレクトリに制限されていることを意味します。二重引用符は、検索パスにcurrentディレクトリが含まれ、その後にシステムインクルードディレクトリが続くことを意味します。

OSが大文字と小文字を区別するファイルシステムを使用している場合、ファイル名の大文字と小文字は区別されます。 WindowsまたはMac OS Xを使用している可能性があります。デフォルトでは、ファイル名の大文字と小文字は区別されません。

27
Greg Hewgill

最初の簡単な質問:

彼らが特定の方法で同様に資本化されているかどうかは重要ですか?

ほとんどの場合、includesはファイルを参照します。コンパイラーは、システムに組み込んでいるファイルを見つけることができるはずです。そのため、ファイルシステムで大文字と小文字が区別されるすべてのシステムで、大文字と小文字mattersが使用されます。最小限の移植性を維持したい場合は、ファイルの名前とincludeを一致させる必要があります。 (すべてのLinux そしてマックOS デフォルトでは大文字と小文字を区別するファイルシステムを持っています。Windowsでは、NTFSを大文字と小文字を区別するように構成することもできます

さて、実際にファイルの名前がどのように関係するのでしょうか?いいえ、インクルージョンに一貫性がある限り、そうではありません。また、包含を容易にするためにパターンに従うことをお勧めします。

ヘッダーファイルをインポートする方法は重要ですか?

この時点では、標準は明確ではなく、実装が異なると、パスも異なります。コンパイラがインクルードされるファイルを検索する場所と順序のセットは実装で定義され、インクルードが山括弧または二重引用符である場合は異なる可能性があるため、標準はそれらが異なる場合があると定義しています。引用符を使用したインクルードでファイルを見つけられなかった場合、コンパイラーはフォールバックして、山括弧で記述されているかのようにインクルードを処理する必要があります。

#include <x.h> // search in order in set1 of directories
#include "x.h" // search in order in set2 of directories
               // if search fails, search also in set1

つまり、ファイルがset1にのみ存在する場合は、両方のタイプのインクルードがそのファイルを見つけます。ファイルがset2に存在するがset1には存在しない場合、引用インクルードのみがそれを見つけます。同じ名前の異なるファイルがset1とset2に存在する場合、それぞれの包含タイプは異なるファイルを見つけて包含します。同じ名前の2つのファイルがset1とset2の共通サブセットに存在するが、セットの順序が異なる場合、各包含タイプは異なるファイルを見つけることができます。

現実の世界に戻ると、ほとんどのコンパイラーはset2に現在のディレクトリのみを含み、set1はすべてのシステムインクルードの場所です(通常、コンパイラーの引数で拡張できます)これらの場合、ファイルが現在のディレクトリにのみ存在する場合、 #include "a.h"は検索しますが、#include <a.h>は検索しません。

さて、それが一般的な振る舞いであるかどうかにかかわらず、C/C++では慣用的な暗黙セマンティクスがいくつかあります。一般的に、角括弧はシステムヘッダーとexternalヘッダーを含めるために使用され、二重引用符はlocalファイルを含めるために使用されます。同じプロジェクトのライブラリをlocalまたはexternalと見なすかどうかについては、灰色のゾーンがあります。つまり、常に二重引用符を含めても機能する場合でも、ほとんどの人は角度引用符を使用して、現在のモジュールの一部ではないヘッダーを参照します。

最後に、私が知っているコンパイラはありませんが、標準では実装(コンパイラ)が標準ヘッダーを実際のファイルとして生成せず、内部で標準ヘッダーのインクルードを処理することを許可しています。これは、理論的には#include "vector"std::vectorクラス(またはその他の標準ヘッダー)の定義を含めることができない唯一のケースです。しかし、これは実際的な問題ではありませんし、そうなるとは思いません。

山かっこは、システムヘッダーディレクトリでヘッダーを探します(例:/usr/include)。引用符は、/path/to/header.h../headers/abc.hなどの絶対パス名または相対パス名です。

他のファイルからクラスにアクセスするには、クラスを含む他のファイルを#includeします。必ずファイルを2回以上インクルードしないようにプログラムを構成してください。

7
Delan Azabani

質問1

ヘッダーファイルをインポートする方法は重要ですか?彼らが特定の方法で同様に資本化されているかどうかは重要ですか?

それは問題ではありませんが、通常の慣行は、

  • システムヘッダーには山括弧を使用します。
  • ユーザー定義ヘッダーのユーザー二重引用符(独自のヘッダー)

質問2&3

別の質問は、(Javaここから)、定義されたファイル外のクラスにどのようにアクセスするのですか?

クラス定義をヘッダーファイルに配置し、クラスを使用する場所にそのヘッダーファイルを含める必要があります。あなたの場合、それは以下のようになります。

//One.h
#ifndef ONE_H
#define ONE_H
class Something
{
public:
    void doSomething(){}

};
#endif

//Two.cpp
#include "One.h"
class SomethingElse
{
   SomeThing *example;
};
7
bjskishore123

まず、#includeはCプリプロセッサディレクティブであり、厳密にはC++言語自体の一部ではありません。あなたはそれについてもっと知ることができます ここ これは特にGNU Cプリプロセッサのためのものなので、使用しているものとは異なる場合があります。常に仮定する必要があると思いますインクルードファイルでの大文字と小文字の区別:そうしないと、コードをUNIXなどの大文字と小文字を区別するOSに移植することが困難になる場合があります。

上記で説明したように、 ""または<>の使用はかなり微妙であり、ほとんどの場合、違いはありません。通常、 ""を使用すると、現在のディレクトリが最初に検索されます。私はこれを次のように使用しない傾向があります:

  • ヘッダーがどこにあるか知っています。コンパイル行では常に-Iを使用してヘッダーを指定します。
  • 以前に、ローカルで作成されたヘッダーのコピーが、取得したいと思っていた中央のコピーを上書きしてしまったことを知りました。

Makeを使用して依存関係ツリーを作成するときなど、いくつかの副作用にも気づきました(問題を完全に思い出せません-いくつかのインクルードと別のインクルードを別の方法で扱いましたが、これは約7年前です)

次に、他のファイルの関数を参照する方法についての質問に答えます ここ /

0
Component 10