2008-10-24 119 views
32

我來自.NET世界,我是寫C++的新手。我只是想知道什麼是命名局部變量和結構成員的首選命名約定。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

謝謝!

回答

53

這種匈牙利符號是相當無用的,如果你不得不改變某種東西的話,那可能比無用的更糟。 (The proper kind of Hungarian Notation是一個不同的故事。)

我建議你使用你的小組做什麼。如果您是該計劃的唯一工作人員,請以任何對您最有意義的方式對其進行命名。

+7

+1鏈接! – nus 2010-11-06 23:14:27

+6

你的第二個陳述是完全錯誤的,你不應該用這種座右銘來發展。在你之後,你永遠不知道誰會在這個項目上工作。你的命名應該使你的代碼明確**給你,你的未來,你和其他人。變量/函數名稱應該有助於理解正在發生的事情。 – 2016-03-23 09:50:33

+1

它錯在哪裏?以一種對你有意義的方式命名變量*是讓你的代碼明確地展示給你的未來自己,如果你有任何編碼經驗的話。 – 2016-03-24 13:43:23

1

匈牙利符號在Win32和MFC API的用戶中很常見。如果你的前任使用它,你可能最好繼續使用它(儘管它很糟糕)。 C++世界的其他部分從未有過這種大腦死亡的習慣,所以如果您使用的不是這些API,則不要使用它。

+1

匈牙利命名法是最複雜的MFC,但C++世界其他地區使用這種符號的最小子集,如m_表示「成員」,p表示「指針」。 – 2008-10-24 22:10:28

1

我認爲你仍然會發現,在Visual C++中編程的大多數商店使用匈牙利符號或至少是淡化版本。在我們的商店中,我們的一半應用程序是舊版C++,頂部有一個閃亮的新C#圖層(中間有一個託管的C++圖層)。我們的C++代碼繼續使用匈牙利符號,但我們的C#代碼使用您提供的符號。我認爲這是醜陋的,但它是一致的。

我說,使用你的團隊想要的任何項目。但是,如果您正在處理遺留代碼或加入團隊,請堅持現有的一致性風格。

16

最重要的是要保持一致。如果您使用的是舊版代碼庫,請使用舊版代碼的命名約定將變量命名爲,並始終如一地使用。如果您正在編寫僅與舊代碼接口的新代碼,請在新代碼中使用您的命名約定,但也要與自己保持一致。

4

我同意其他答案。爲了保持一致性,繼續使用傳承下來的風格,或者制定一個適用於您的團隊的新慣例。團隊一致認同這一點很重要,因爲幾乎可以保證你將會改變相同的文件。話雖如此,有些事情,我發現在過去很直觀:

類/結構的成員變量應該站出來 - 我通常有m個_
全局變量應該站出來前綴他們都 - usuall前綴相剋_
在一般的變量應該與小寫開始一般
函數名稱應當使用大寫開頭的
宏和可能的枚舉應該全部大寫
所有名稱應該描述函數/變量做什麼,不應該描述其類型或值。

6

在這個例子中,「ppMyObjects」除了有點難看外,還有什麼不喜歡或者嘲笑的?我沒有強烈的意見,但它確實傳達了有用的信息一目瞭然,「MyObjects」沒有。

2

我自己是一個匈牙利符號的人,因爲我發現它給代碼提供了可讀性,而且我更喜歡自我記錄代碼來評論和查找。

這就是說,我認爲你可以做出犧牲你喜歡的風格和一些額外的團隊可維護性的情況。爲了統一代碼的可讀性,我不會購買一致性的論點,尤其是如果您爲了一致性而降低可讀性......它只是沒有意義。然而,與你一起工作的人相處可能會對看待變量的類型更加混淆。

1

這一切都歸個人喜好。我曾爲2家公司提供類似的方案,其中成員變量名爲m_varName。我從來沒有在工作中看到匈牙利符號的使用,真的不喜歡它,但又一次偏好。我一般的感覺是,IDE應該關心告訴你它是什麼類型的,所以只要名稱足夠描述它的功能(m_color,m_shouldBeRenamed),那就沒問題。我喜歡的另一件事是成員變量,局部變量和常量命名之間的區別,所以它很容易看到函數中發生了什麼以及變量來自哪裏。 會員:m_varName 常數:c_varName 地方:varName的

15

號 「錯誤匈牙利命名法」 - 尤其是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 

然而,保持遺留代碼,不會遵循一些約定一致(即使鬆散地)時,你應該堅持使用有約定 - 至少在現有模塊/編譯單元得以維持。

我的推理:編碼標準的目的是遵守最少意外的原則。始終如一地使用一種風格比使用哪種風格更重要。

0

如果您使用CamelCase,則約定是爲類struct和非基元類型名稱首字母大寫 ,小寫數據成員的第一個字母。 方法的大寫往往是混雜的包,我的方法往往是動詞,並已經parens distingish,所以我沒有資本化的方法。

我個人不喜歡讀碼駝峯,寧願強調小寫用於 數據和方法標識符,大寫類型和保留爲縮略詞 大寫和罕見的情況下,我使用宏(警告這是一個宏) 。

1

我也更喜歡CamelCase,的確我大多數人都見過在C++中使用CamelCase的人。本人來說,我不使用任何前綴期待私有/ protected成員和接口:

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

請參閱High Integrity C++ Coding Standard Manual獲取更多靈感。

2

我們的團隊使用Google C++ code convention

這是變量名的示例:

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

string tableName; // Bad - mixed case.