web-dev-qa-db-ja.com

C ++の変数の命名規則

私は.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

ありがとう!

33
stung

この種のハンガリー記法はかなり役に立たず、何かのタイプを変更する必要がある場合は役に立たない可能性があります。 ( properハンガリー表記法の種類 は別の話です。)

私はあなたのグループがすることなら何でも使うことをお勧めします。あなたがプログラムで作業している唯一の人なら、あなたにとって最も意味のある名前を付けてください。

55
Head Geek

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

16
Adam Rosenfield

いいえ。「間違ったハンガリー記法」-特に二重間接指定のpp-は、あなたが書くことができる初期のCコンパイラにとっては意味がありました。

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

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

「オタクの頭によってリンクされた」「真のハンガリー表記」は依然として有効なオプションですが、必ずしも優先されるわけではありません。現代のC++アプリケーションには通常、数十または数百のタイプがあり、適切なプレフィックスは見つかりません。

私はまだそれをミックスしなければならないいくつかのケースでそれをローカルで使用しています。問題ドメイン内で非常に類似した名前または同じ名前さえ持っている整数および浮動小数点変数。

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

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

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

15
peterchen

この例で「ppMyObjects」について嫌いなものやm笑すべきものは何ですか?どちらにしても強い意見はありませんが、「MyObjects」にはない便利な情報を一目で伝えます。

6
xyz

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

クラス/構造体メンバー変数は目立つはずです-私は通常、すべてに接頭辞m_を付けます
グローバル変数が目立つはずです-通常の接頭辞g_
変数は一般に小文字で始まる必要があります
関数名は一般に大文字で始まる必要があります
マクロおよび場合によっては列挙型はすべて大文字にする必要があります
すべての名前は、関数/変数が行うことを説明する必要があり、そのタイプまたは値を説明することはありません。

4
Marcin

私はハンガリーの記者です。なぜなら、コードを読みやすくするためであり、コメントや検索よりも自己文書化コードを好むからです。

とはいえ、好みのスタイルを犠牲にして、チームの団結のためにいくつかの追加の保守性を犠牲にすることはできると思います。一貫性のために読みやすさを低下させる場合は特に、一貫したコードの読みやすさのために一貫性の引数を購入しません...それは意味がありません。ただし、作業対象の人とうまくやっていくことは、変数を見る型についてもう少し混乱する価値があるかもしれません。

2
Nick

そのすべては個人的な好みに依存します。私は2つの会社で働いており、どちらも同様のスキームを使用しており、メンバー変数はm_varNameという名前です。私は職場でハンガリー語の表記法が使われているのを見たことがありません。私の一般的な感じは、名前がそれが何をするかを十分に説明している限り(m_color、m_shouldBeRenamed)、それがOKである限り、IDEはそれがどんなタイプであるかを注意する必要があるということです。私が好きな他のことは、メンバー変数、ローカル変数、定数命名の違いです。そのため、関数で何が起こっているのか、変数がどこから来たのかを簡単に確認できます。メンバー:m_varName定数:c_varNameローカル:varName

1
DavidG

ハンガリー語表記は、Win32およびMFC APIのユーザーの間で一般的でした。前任者がそれを使用していた場合、おそらくそれを使用し続けるのが最善です(それは最悪ですが)。 C++の世界の残りの部分では、この頭の痛い慣習がなかったため、これらのAPI以外のものを使用している場合は使用しないでください。

1
Leon Timmermans

Visual C++でプログラムを作成しているほとんどのショップでは、ハンガリー語表記または少なくとも骨抜きバージョンを使用していることに気付くでしょう。私たちのショップでは、アプリの半分はレガシーC++であり、上部に光沢のある新しいC#レイヤーがあります(中間にマネージC++レイヤーがあります)。C++コードは引き続きハンガリー語表記を使用しますが、C#コードは提示された表記を使用します。見苦しいと思いますが、一貫しています。

私は言う、あなたのチームがあなたのプロジェクトに望むものは何でも使ってください。ただし、レガシーコードで作業している場合やチームに参加している場合は、一貫性を保つために存在するスタイルを使用してください。

1
Rob Prouse

また、私はCamelCaseを好みます。実際、C++でCamelCaseを使用している人々を見てきました。個人的に私はプライベート/保護されたメンバーとインターフェースに期待するプレフィックスを使用していません:

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;
};

インターフェイスには、定義ごとに、後で実装する必要がある純粋な仮想メソッドのみが含まれます。しかし、ほとんどの場合、抽象クラスを好みますが、これは別の話です。

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

高整合性C++コーディング標準マニュアル を参照してください。

1
bkausbk

私のチームはこれに従います Google C++コード規約

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

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

string tableName;   // Bad - mixed case.
1
Tho

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

個人的には、CamelCaseコードを読むのは好きではありませんが、データとメソッドの識別子にはアンダースコアを使用し、頭字語には大文字を使用し、マクロを使用することはまれです(これはMACROであることに注意してください)。

0
Roger Nelson