web-dev-qa-db-ja.com

デフォルト値が同じでも、列挙値を明示的に定義しますか?

列挙型の値が重要な場合があります。それらが一意である必要はなく、特定の値を持つ必要もあります。そのような場合、たとえデフォルトと一致していても、値を明示的に定義する必要がありますか?例:

enum Car {
    DeLorean = 0,
    Lada = 1
};

何らかの理由で、アプリケーションがDeLoreanLadaにこれらの特定の値があると想定していると想像してください。ちなみに、それらはデフォルト値と同じですが、明示的な定義を使用する必要がなくなったことを意味しますか?

暗黙のうちに残しておくと、不安になります。それらを明示的に定義することは、特定の値が重要であり、次のような間違いを防ぐのに役立つことを将来のプログラマーに伝えることです。

enum Car {
    Dacia,
    DeLorean,
    Lada
};

上記の例では、私が言及した制限を認識していない別のプログラマーが新しいenum値を導入し、コードを整然と保ちたい場合は、アルファベット順に配置します。ただし、DeLoreanLadaの数値が異なり、潜在的にサイレントになるバグが導入されました。

私の推論は(当然のことながら)私には正しいようですが、以前使用していた会社のコードレビューチームは同意しませんでした。私が間違っている?

4
Paul

これは非常に判断の呼びかけですが、明示的な値を使用する方法であることに加え、最初に明示的な値の重要性を説明するコメントも同意します。

この方法で実行している著名なプロジェクトの例として、ClangのASTシリアライゼーションを見てください。これは巨大な列挙型を使用して、すべてのAST =ノード。列挙型には明示的な値があります。

とはいえ、重要なことが他にもあるときに機能する古いコードに触れることは最善のアイデアではないというアーキテクチャチームの意見にも共感します。

ただし、妥協案は気に入らない。それは何も追加しません。

6
Sebastian Redl

これらの値を保存または送信する場合、それらは特定のものでなければなりません。通常、両方の当事者が共有するヘッダーファイルでプロトコルを定義します。何らかのバージョン管理メカニズムがあれば、大きな問題にはなりません。ただし、明示的にすることをお勧めします。私はコードで「あなたの言っていることが言う」のファンです。それは何の費用もかかりませんし、コードははるかに読みやすくなります。

ただし、enum値が格納されていない内部モジュールおよびAPIの場合、デフォルトで十分です。列挙型自体の値は重要ではないことを伝えています。重要なのは、それらの値の意味と、ストンガータイピングを使用してコードが何を使用しているかを明確にし、無効な値が使用されないようにすることです。

2
Tereus Scott

C++ 11のenum class; enumにある微妙なバグを取り除きながら、明示的な値の必要性を排除することができます。

1
Fabio A. Correa

新しいコードでは、特定の列挙が特定の値と等しいことがシステムまたはビジネス要件の一部である場合、それは明確に明示され、コメントされ、文書化されている必要があります。そうしないと、メンテナンスの悪夢を招きます。

あなたのシナリオで、このような列挙型を明示的にするのを遅らせる唯一の要因は、これが動作中のコードベースからの古いコードであり、他のタスクが優先される可能性があるという事実です。

0
Matt Coubrough

列挙型では、3つの哲学が機能し、1つは機能しません

  1. 値にとらわれない-すべてのオプションにデフォルト値を使用し、基礎となる値は無関係
  2. シーケンス固有-最初の値を定義し、他のすべてを増分として残します
  3. 値固有-すべてのオプションの値を指定し、値は重要です(例:通信メッセージID)

しないもの

  1. 一部指定-一部の値が指定され、一部は指定されていません

オプション(4)はMISRA C(および他のそのような標準)で非推奨になっています...同様に、(2)が必要である理由(デフォルト= 0以外)について私は純粋主義者に質問しますが、これにはおそらく正当な理由があります。

もちろん、値が指定されている場合は、その理由を説明する適切なドキュメントが必要です。

私見列挙の根本的な値を知ることに依存することは非常に危険であり、さらにはシーケンスを想定するためにさらに危険です-enum型をインクリメントおよびデクリメントするときに発生する可能性がある問題...

0
Andrew

これは純粋にソフトウェアコーディングガイドラインの呼び出し(プロセスコンプライアンスの呼び出し)です。

列挙値は多くのアルゴリズムの核心であり、細心の注意を払って処理する必要があります。使用法のもう1つのオプションは、理解を明確にするために、列挙定数の名前がその名前自体を介して値を伝える方がよいということです。

例:

enum retries {
    RETRY_ZERO,
    RETRY_ONE,
    RETRY_TWO,
    RETRY_THREE
};
0