我经常在教程、示例和其他主要与游戏开发相关的代码中看到m_
用于变量(m_World
、m_Sprites
,...)的前缀。
为什么人们要为变量添加前缀m_
?
这是定义作为成员变量的变量的典型编程实践。因此,当您以后使用它们时,您无需查看它们的定义位置即可了解其范围。如果您已经知道范围并且正在使用类似 intelliSense的东西,这也很棒,您可以从m_
开始,并显示所有成员变量的列表。匈牙利语表示法的一部分,请参阅此处示例中有关范围的部分。
在Clean Code: A Handbook of Agile Software Craftmanship中,有一个明确的建议不要使用此前缀:
您也不再需要在成员变量前面加上
m_
。你的类和函数应该足够小,以至于你不需要它们。
还有一个示例(C# 代码):
不良做法:
public class Part
{
private String m_dsc; // The textual description
void SetName(string name)
{
m_dsc = name;
}
}
良好做法:
public class Part
{
private String description;
void SetDescription(string description)
{
this.description = description;
}
}
在明确歧义的情况下,我们使用语言构造来引用成员变量(即,description
成员和description
参数):this
。
这是C++的常见做法。这是因为在C++中,成员函数和成员变量的名称不能相同,并且 getter 函数的命名通常没有"get"前缀。
class Person
{
public:
std::string name() const;
private:
std::string name; // This would lead to a compilation error.
std::string m_name; // OK.
};
main.cpp:9:19: error: duplicate member 'name' std::string name; ^ main.cpp:6:19: note: previous declaration is here std::string name() const; ^ 1 error generated.
http://coliru.stacked-crooked.com/a/f38e7dbb047687ad
"m_"表示"成员"。前缀"_"也很常见。
您不应该在通过使用不同的约定/语法来解决此问题的编程语言中使用它。
m_
前缀通常用于成员变量 - 我认为它的主要优点是它有助于在公共属性和支持它的私有成员变量之间建立明确的区别:
int m_something
public int Something => this.m_something;
它可以帮助为支持变量制定一致的命名约定,而m_
前缀是实现此目的的一种方法 - 一种适用于不区分大小写的语言的方法。
这有多有用取决于您使用的语言和工具。具有强大重构工具和智能感知的现代 IDE 对此类约定的需求较少,这当然不是执行此操作的唯一方法,但无论如何都值得了解这种做法。
如其他答案所述,m_
前缀用于指示变量是类成员。这与匈牙利符号不同,因为它不指示变量的类型,而是指示其上下文。
我在C++中使用m_
,但在其他一些语言中不使用"这个"或"自我"是强制性的。我不喜欢看到"this->"与C++一起使用,因为它会使代码混乱。
另一个答案说m_dsc
是"不良做法",而"描述"是"良好做法",但这是一个红鲱鱼,因为那里的问题是缩写。
另一个答案是键入this
会弹出智能感知,但任何好的IDE都会有一个热键来弹出当前类成员的IntelliSense。
洛克希德马丁公司使用了一个3前缀的命名方案,这个方案非常好用,尤其是在阅读其他人的代码时。
Scope Reference Type(*Case-by-Case) Type
member m pointer p integer n
argument a reference r short n
local l float f
double f
boolean b
所以。。。
int A::methodCall(float af_Argument1, int* apn_Arg2)
{
lpn_Temp = apn_Arg2;
mpf_Oops = lpn_Temp; // Here I can see I made a mistake, I should not assign an int* to a float*
}
把它当作它的价值。
如许多其他响应中所述,m_ 是表示成员变量的前缀。它在C++世界中普遍使用,并传播到其他语言,包括Java。
在现代 IDE 中,它是完全多余的,因为语法突出显示可以清楚地知道哪些变量是局部变量,哪些变量是成员。然而,当语法高亮出现在 90 年代后期时,这个惯例已经存在了很多年,并且已经牢固确立(至少在C++世界)。
我不知道你指的是哪些教程,但我猜他们正在使用该约定,因为有两个因素之一:
- 它们是C++教程,由习惯于m_惯例的人编写,和/或......
- 它们以纯(等宽)文本编写代码,没有语法突出显示,因此m_约定对于使示例更清晰非常有用。
其他人提到它的意思是类成员。Qt是一个流行的c ++框架,它使用这种符号,所以很多C++GUI教程都使用m_
。您可以看到他们几乎所有的示例都对类成员使用m_
。就个人而言,我使用m_
因为它比this->
短并且感觉紧凑。
为了完成当前的答案,并且由于问题不是特定于语言的,一些C项目使用前缀m_
来定义特定于文件的全局变量 - 对于作用域大于其定义的文件的全局变量,则使用前缀g_
。
在这种情况下,使用前缀m_
定义的全局变量应定义为static
。
有关使用此约定的项目示例,请参阅 EDK2(UEFI 开源实现)编码约定。
我还没有看到的一个论点是,像m_
这样的前缀可以用来防止与#define
宏的名称冲突。
正则表达式从诅咒/诅咒中搜索#define [a-z][A-Za-z0-9_]*[^(]
/usr/include/term.h
。