web-dev-qa-db-ja.com

列挙型:.hで実行できますか、それとも.cppにとどまる必要がありますか?

私が次のようなものを持っている場合:

enum
{
    kCP_AboutBox_IconViewID = 1,
    kCP_AboutBox_AppNameViewID = 2,
    kCP_AboutBox_VersionViewID = 3,
    kCP_AboutBox_DescriptionViewID = 4,
    kCP_AboutBox_CopyrightViewID = 5
};

私の.cppでは.hに入れることができますか?

さらに、クラス定義、変数など以外に、他のあまり知られていないものを.hに入れることができます。

24
user147502

.hファイルは基本的に、コンパイル時に、インクルードされている.cpp(または.hファイル)の上に配置される単なるコードです。したがって、.cppファイルから.hに任意のコードを配置できます。正常にコンパイルされるはずです。

ただし、重要なのはデザインです。 .hファイルを含めているコードにコードを公開する必要がある場合は、コード(列挙型など)を.hファイルに配置する必要があります。ただし、列挙型がヘッダーの.cpp実装のコードにのみ固有である場合は、.cppファイル内にカプセル化する必要があります。

39
IAmFledge

次のようなヘッダーには、ヘッダーインクルードガードを使用することを忘れないでください。

#ifndef header_name_h
#define header_name_h
...
#endif

これは、複数のヘッダーにヘッダーが含まれている場合に、1つの定義ルールを維持するのに役立ちます。

更新:

それ以来、最新バージョンのVisual Studiogccの両方で次のことが可能であることがわかりました。

#pragma once

また、これまでにない:

using namespace <name>;

これは奇妙なあいまいさの問題を引き起こす可能性があるため、ヘッダーにあります。

8
quamrana

一般に、列挙型は型定義として使用され、常にヘッダーファイルに含まれている必要があります。考えるべきことはその範囲です。

列挙型がヘッダーのスコープ外に配置された場合、ヘッダーファイルを含むすべてのものでグローバルに使用できます。代わりに、列挙型にクラス自体だけがアクセスできるようにしたい場合は、クラスのプライベートセクションに配置できます。

一般に、列挙型をグローバルスコープにするのではなく、名前空間またはクラスのパブリックセクションに配置する必要があります。次に、を介して列挙型にアクセスできます

NamespaceOrClass::EnumValue

また、補足として、列挙型は最初に指定した値(または0)から値を自動的に繰り返します。

enum
{
    kCP_AboutBox_IconViewID = 1,
    kCP_AboutBox_AppNameViewID = 2,
    kCP_AboutBox_VersionViewID = 3,
    kCP_AboutBox_DescriptionViewID = 4,
    kCP_AboutBox_CopyrightViewID = 5
};

とまったく同じです

enum
{
    kCP_AboutBox_IconViewID = 1,
    kCP_AboutBox_AppNameViewID,
    kCP_AboutBox_VersionViewID,
    kCP_AboutBox_DescriptionViewID,
    kCP_AboutBox_CopyrightViewID
};

それは問題やエラーではなく、本当に文体的なものです。

4
Zeroshade

はい、列挙型定義はヘッダー(.h)ファイルに入れることができます。ただし、.cppファイルで定義を繰り返さないでください。

4
mipadi

はい、もちろん、.hファイルに入れることができます。 .hファイルに含めるべきではないものは、グローバルオブジェクト初期化子などの複数のオブジェクトにインクルードされた場合に問題を引き起こす可能性があるものだけです。

3
Andrew Medico

単一定義規則は、3.2/5でそれを許可します。以下のすべてをヘッダーに入れることができ、異なる翻訳単位に複数回含めることができます。

クラスタイプ(9節)、列挙型(7.2)、外部リンケージを使用したインライン関数(7.1.2)、クラステンプレート(14節)、非静的の定義は複数存在する可能性があります。関数テンプレート(14.5.5)、クラステンプレートの静的データメンバー(14.5.1.3)、クラステンプレートのメンバー関数(14.5.1.1)、または一部のテンプレートパラメーターが指定されていないテンプレートの特殊化(14.7、14.5.4) )各定義が異なる翻訳単位で表示され、定義が次の要件を満たしている場合、プログラム内。

要件は基本的に、各定義が同じでなければならないということです。列挙型自体に名前がない場合は、そのルールの対象外であることに注意してください。別の変換ユニットでの各定義は、新しい列挙型を定義し、互いに衝突しません。

公開することになっている場合は、ヘッダーに配置することをお勧めします。それらを実装ファイルに配置することは、その単一のファイルに対してプライベートであると想定される場合に適しています。後者の場合は、名前のない名前空間に配置するか、名前を付けないようにして(列挙の例の場合のように)、同じ名前の別の列挙と衝突しないようにします。

十分な情報がありませんが、.hだけでなくクラス内でも列挙型を宣言できるかもしれません。変数のスコープを最小限に抑えることを忘れないでください。
列挙型が特定のクラスに関連している場合は、クラス内で宣言する必要があります。

0
Matthieu