2008-10-24 92 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.