web-dev-qa-db-ja.com

名前空間とヘッダーガードと名前の競合

C++には、同じ名前のものが衝突しないようにする名前空間があります。

ヘッダーガードは別の目的を果たします。同じヘッダーを2回includeingするのを防ぎます。ただし、同じ問題が発生する可能性があります。異なるファイルの2つのヘッダーガードが同じ一般的な名前を使用するとどうなるでしょうか。 LinkedListクラスを持つ2つのライブラリがある場合はどうなりますか。

#ifndef LinkedList_H
#define LinkedList_H

// stuff

#endif

コードを一意に識別するためのこれら2つの手段がなぜそれほど異なるのですか?これは、一方の洗練された言語機能の1つであり、もう一方の任意の文字列によるマクロの仕掛けのようなものです。ヘッダーガードで名前の競合が問題にならないのはなぜですか?重複するincludeだけでなく、名前の競合も防ぐために、名前空間を名前空間と同じように一意にするために、名前空間をヘッダーガードの一部にしないでください。

3
null

私が使用する1つの方法は、他の名前と衝突する可能性が実質的にゼロである、より複雑なマクロ名を作成することです。これは、次のコンポーネントから構築できます。

  • プロジェクト名
  • 名前空間名
  • ファイル名
  • 乱数またはGUID

例:

#if !defined MYPROJECT_MYNAMESPACE_FOO_HPP_9E72F091C4A833D7
#define ...

やりすぎ?はい。簡単ですか?はい。非常に小さな衝突の可能性があるので、それを書いて忘れることはありますか?はい。

2
user22815

ヘッダーガードは、(ヘッダー自体と同様に)プリプロセッサーの一部であるため、名前空間ほど洗練されていません。プリプロセッサーは、Cから継承されたC++の非常に原始的な部分です。

一般的な規則は、プロジェクトとプロジェクト内パスを接頭辞として追加することです。

#ifndef MYPROJECT_UTILITY_CONTAINERS_LINKED_LIST_HPP
#define MYPROJECT_UTILITY_CONTAINERS_LINKED_LIST_HPP

もちろんそれだけではありません。

3
Sebastian Redl
#pragma once

本当に、それは すべての主要なコンパイラ (プリプロセッサ)でサポートされています。いくつかのプロジェクトはそれを使用するように動きます:たとえばQt Creator。はい、それは非標準です。

3
Monah Tuk