我经常在教程,示例和其他主要与游戏相关的代码中看到 m_
前缀用于变量(m_World
,m_Sprites
,...)发展。
为什么人们会在变量中添加前缀m_
?
答案 0 :(得分:88)
这是用于定义作为成员变量的变量的典型编程实践。因此,当您以后使用它们时,您不需要查看它们的定义位置以了解它们的范围。如果您已经知道范围并且使用 intelliSense 之类的东西,这也很棒,您可以从m_
开始,并显示所有成员变量的列表。匈牙利表示法的一部分,请参阅examples here中有关范围的部分。
答案 1 :(得分:69)
在清洁代码:敏捷软件工艺手册中,明确建议不要使用此前缀:
您也不需要使用
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
。
答案 2 :(得分:11)
m_
前缀通常用于成员变量 - 我认为它的主要优点是它有助于在公共属性和支持它的私有成员变量之间创建一个明确的区别:
int m_something
public int Something => this.m_something;
支持变量的命名约定可以有所帮助,m_
前缀是这样做的一种方式 - 一种适用于不区分大小写的语言。
这有多大取决于您使用的语言和工具。具有强大的重构工具和智能感知的现代IDE对此类约定的需求较少,并且它当然不是这样做的唯一方法,但在任何情况下都值得了解这种做法。
答案 3 :(得分:11)
这是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.
“m_”表示“成员”。前缀“_”也很常见。
您不应该在使用不同约定/语法解决此问题的编程语言中使用它。
答案 4 :(得分:6)
如其他答案所述,m_
前缀用于表示变量是类成员。这与匈牙利表示法不同,因为它不表示变量的类型,而是表示其上下文。
我在C ++中使用m_
但在其他语言中不使用'this'或'self'是强制性的。我不喜欢看'this->'与C ++一起使用,因为它使代码混乱。
另一个答案说m_dsc
是“不良做法”和“描述”。是“良好做法”,但这是一个红色的鲱鱼,因为那里的问题是缩写。
另一个答案说,输入this
会弹出IntelliSense,但任何好的IDE都会有一个热键,可以为当前的班级成员弹出IntelliSense。
答案 5 :(得分:2)
如许多其他回复中所述,m_是表示成员变量的前缀。它通常在C ++世界中使用,并且也传播到其他语言,包括Java。
在现代IDE中,它完全是多余的,因为语法高亮显示哪些变量是本地,哪些是成员。然而,到90年代后期出现语法高亮时,该惯例已经存在多年并且已经确定(至少在C ++世界中)。
我不知道您指的是哪些教程,但由于以下两个因素之一,我猜他们正在使用该约定:
答案 6 :(得分:2)
要完成当前答案,并且问题不是特定于语言的,某些C项目使用前缀m_
来定义特定于文件的全局变量,而g_
则用于范围大于定义的文件。
在这种情况下,应将以前缀m_
定义的全局变量定义为static
。
有关使用此约定的项目示例,请参见EDK2 (a UEFI Open-Source implementation) coding convention。
答案 7 :(得分:1)
洛克希德·马丁公司(Lockheed Martin)使用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 afArgument1, int* apnArg2)
{
lpnTemp = apnArg2;
mpfOops = lpnTemp; // Here I can see I made a mistake, should ! be floating type
}
以它的价值来接受它。也许在变量名前加下划线。
答案 8 :(得分:1)
其他人提到它意味着一个班级成员。 Qt 是一种流行的 C++ 框架,它使用这种表示法,因此很多 C++ GUI 教程都使用 m_
。你可以看到他们几乎所有的例子都使用 m_
作为班级成员。就我个人而言,我使用 m_
,因为它比 this->
短并且感觉紧凑。
答案 9 :(得分:0)
我还没有看到的一个论点是,可以使用诸如m_
之类的前缀来防止名称与#define
'd宏冲突。
正则表达式从curses / ncurses中搜索#define [a-z][A-Za-z0-9_]*[^(]
中的/usr/include/term.h
。