37

私は .NET の世界から来て、C++ を書くのは初めてです。ローカル変数と構造体メンバーの命名に関して、どのような命名規則が好まれるのか疑問に思っています。

たとえば、私が継承したレガシー コードには、次のようなものがたくさんあります。

struct MyStruct
{
   TCHAR           szMyChar[STRING_SIZE];
   bool            bMyBool;
   unsigned long   ulMyLong;
   void*           pMyPointer;
   MyObject**      ppMyObjects;
}

C# のバックグラウンドを持つ私は、ハンガリー語表記の変数を見てショックを受けました (最初に pp プレフィックスを見たとき、笑いが止まりませんでした)。

代わりに、このように変数に名前を付けたいと思います(ただし、最初の文字を大文字にすることが適切な慣例であるかどうかはわかりません。他の方法を見てきました(以下のリンクを参照))。

struct MyStruct
{
   TCHAR           MyChar[STRING_SIZE];
   bool            MyBool;
   unsigned long   MyLong;
   void*           MyPointer;
   MyObject**      MyObjects;
}

私の質問: これ (以前の方法) は、C++ で変数に名前を付けるための推奨される方法ですか?

参考文献:

http://geosoft.no/development/cppstyle.html

http://www.syntext.com/books/syntext-cpp-conventions.htm

http://ootips.org/hungarian-notation.html

ありがとう!

4

12 に答える 12

61

その種のハンガリー語表記法はかなり役に立たず、何かの型を変更する必要がある場合は、役に立たないよりも悪い可能性があります。(適切な種類のハンガリー記法は別の話です。)

あなたのグループがすることは何でも使うことをお勧めします。プログラムに取り組んでいるのがあなただけの場合は、最もわかりやすい名前を付けてください。

于 2008-10-24T19:07:42.033 に答える
17

最も重要なことは、一貫性を保つことです。レガシ コード ベースを使用している場合は、レガシ コードの命名規則に従って変数と関数に名前を付けます。古いコードとのみやり取りする新しいコードを作成している場合は、新しいコードで命名規則を使用しますが、自分自身にも一貫性を持たせてください。

于 2008-10-24T19:08:41.233 に答える
15

いいえ。「間違ったハンガリアン記法」、特に二重間接参照の pp は、初期の C コンパイラではある程度の意味がありました。

int * i = 17;
int j = ***i;

コンパイラからの警告さえありません (そして、それは適切なハードウェア上で有効なコードでさえあるかもしれません...)。

「真のハンガリー表記法」(head Geek によってリンクされている) は、IMO ではまだ有効なオプションですが、必ずしも優先されるわけではありません。最近の C++ アプリケーションには通常、数十または数百の型があり、適切な接頭辞が見つかりません。

問題のドメインで非常に似た名前または同一の名前を持つ整数変数と浮動小数点変数などを混在させる必要があるいくつかのケースでは、まだローカルで使用しています。

float fXmin, fXmax, fXpeak; // x values of range and where y=max
int   iXmin, iXMax, iXpeak; // respective indices in x axis vector

ただし、いくつかの規則に一貫して従うレガシー コードを維持する場合 (緩い場合でも)、そこで使用されている規則に固執する必要があります - 少なくとも既存のモジュール/コンパイル ユニットは維持されます。

私の推論: コーディング標準の目的は、最小の驚きの原則に準拠することです。どのスタイルを使用するかよりも、1 つのスタイルを一貫して使用することが重要です。

于 2008-10-24T22:02:05.457 に答える
5

この例の「ppMyObjects」について、やや醜いことを除けば、何を嫌い、または嘲笑する必要がありますか? どちらにしても強い意見はありませんが、"MyObjects" にはない有益な情報が一目でわかります。

于 2008-10-24T19:23:34.450 に答える
3

ここで他の回答に同意します。一貫性を保つために、受け継がれてきたスタイルを引き続き使用するか、チームに適した新しい規則を考え出してください。同じファイルを変更することがほぼ保証されているため、チームが同意していることが重要です。そうは言っても、私が過去に非常に直感的に見つけたいくつかのこと:

クラス/構造体のメンバー変数は目立つべきです - 私は通常、それらすべてに m_ という接頭辞を付けます
グローバル変数は目立つべきです - g_の通常の接頭辞
変数は一般的に小文字で始める必要があります
関数名前は一般に大文字で始まる
必要があり、場合によっては列挙型はすべて大文字にする必要があります
すべての名前は、関数/変数が何をするかを説明する必要があり、その型や値を説明するものではありません。

于 2008-10-24T19:16:28.520 に答える
2

私自身、ハンガリー語表記法を愛用しています。なぜなら、それによってコードが読みやすくなり、コメントやルックアップよりも自己文書化コードの方がずっと好きだからです。

とは言うものの、好みのスタイルを犠牲にして、チームの結束のために保守性をいくらか追加することを主張できると思います。特に一貫性のために可読性を低下させる場合は、統一されたコードの可読性のために一貫性の議論を購入しません...それは意味がありません。ただし、一緒に仕事をしている人々と仲良くすることは、変数を見る型についてもう少し混乱する価値があるかもしれません。

于 2008-10-24T19:43:42.647 に答える
1

私のチームは、次のGoogle C++ コード規則に従います。

これは変数名のサンプルです:

string table_name;  // OK - uses underscore.
string tablename;   // OK - all lowercase.

string tableName;   // Bad - mixed case.
于 2014-01-20T05:17:54.370 に答える
1

そのすべては個人的な好みにかかっています。私は、メンバー変数が m_varName という名前の、同様のスキームを持つ 2 つの会社で働いてきました。仕事でハンガリー語の表記法が使われているのを見たことがなく、本当に好きではありませんが、やはり好みの問題です。私の一般的な感じは、名前がその機能を十分に説明している限り ( m_color, m_shouldBeRenamed )、それで問題ないということです。私が気に入っているもう 1 つの点は、メンバー変数、ローカル変数、および定数の命名の違いです。そのため、関数で何が起こっているのか、変数がどこから来ているのかを簡単に確認できます。メンバー: m_varName 定数: c_varName ローカル: varName

于 2008-10-24T19:44:11.350 に答える
1

Win32 および MFC API のユーザーの間では、ハンガリー語表記が一般的でした。あなたの前任者がそれを使用していた場合は、おそらくそれを引き続き使用することができます (たとえそれが悪いとしても)。残りの C++ の世界では、このような脳死状態の慣習はありませんでした。そのため、それらの API 以外のものを使用している場合は使用しないでください。

于 2008-10-24T19:06:51.520 に答える
1

Visual C++ でプログラムするほとんどのショップは、ハンガリー語表記法または少なくともそれを骨抜きにしたバージョンに固執していることに今でも気付くと思います。当店では、アプリの半分は従来の C++ であり、その上に光沢のある新しい C# レイヤー (中央にマネージ C++ レイヤーがあります) があります。C++ コードは引き続きハンガリー語表記を使用しますが、C# コードはあなたが提示したような表記法を使用します。私はそれが醜いと思いますが、一貫しています。

チームがプロジェクトに必要なものを何でも使用してください。ただし、レガシー コードに取り組んでいる場合やチームに参加している場合は、一貫性を保つために現在のスタイルに固執してください。

于 2008-10-24T19:08:18.193 に答える
1

また、私はキャメルケースを好みます。実際、ほとんどの人が C++ でキャメルケースを使用しているのを見てきました。個人的には、プライベート/保護されたメンバーとインターフェイスを除いて、プレフィックスは使用しません。

class MyClass : public IMyInterface {
public:
    unsigned int PublicMember;
    MyClass() : PublicMember(1), _PrivateMember(0), _ProtectedMember(2) {}
    unsigned int PrivateMember() {
        return _PrivateMember * 1234; // some senseless calculation here
    }
protected:
    unsigned int _ProtectedMember;
private:
    unsigned int _PrivateMember;
};
// ...
MyClass My;
My.PublicMember = 12345678;

パブリック メンバーのプレフィックスを省略することにした理由: パブリック メンバーは構造体のように直接アクセスでき、プライベート名と競合しないためです。アンダースコアを使用する代わりに、メンバーの最初の小文字を使用している人も見てきました。

struct IMyInterface {
    virtual void MyVirtualMethod() = 0;
};

Interfaces には、定義ごとに、後で実装する必要がある純粋仮想メソッドのみが含まれています。ただし、ほとんどの場合、私は抽象クラスを好みますが、これは別の話です。

struct IMyInterfaceAsAbstract abstract {
    virtual void MyVirtualMethod() = 0;
    virtual void MyImplementedMethod() {}
    unsigned int EvenAnPublicMember;
};

さらなるインスピレーションについては、 High Integrity C++ Coding Standard Manualを参照してください。

于 2012-05-15T12:55:43.717 に答える
0

CamelCase を使用する場合、慣習として、クラスの構造体と非プリミティブ型名の最初の文字を大文字にし、データ メンバーの最初の文字を小文字にします。メソッドの大文字化は混合バッグになる傾向があり、私のメソッドは動詞になる傾向があり、すでに括弧で区別されているため、メソッドを大文字化しません。

個人的には、キャメルケースのコードを読むのは好きではなく、データとメソッドの識別子には小文字のアンダースコアを使用し、型を大文字にし、頭字語には大文字を使用し、マクロを使用するまれなケース (警告はマクロです) を好みます。

于 2008-12-20T21:12:34.497 に答える