我经常在教程、示例和其他与游戏开发相关的代码中看到m_前缀用于变量(m_World、m_Sprites等)。

为什么人们在变量前加前缀m_ ?


当前回答

正如在许多其他响应中所述,m_是一个表示成员变量的前缀。它在c++世界中被广泛使用,并传播到其他语言中,包括Java。

在现代IDE中,这完全是多余的,因为语法高亮显示使得哪些变量是局部变量,哪些变量是成员变量变得很明显。然而,当语法高亮显示在90年代末出现时,这个约定已经存在了很多年,并且被牢固地设定了(至少在c++世界中是这样)。

我不知道你指的是哪个教程,但我猜他们使用惯例是由于以下两个因素之一:

它们是c++教程,由习惯m_约定的人编写,和/或… 他们用纯(等宽)文本编写代码,没有语法高亮显示,因此m_约定有助于使示例更清晰。

其他回答

在《干净代码:敏捷软件工艺手册》中,明确建议不要使用这个前缀:

你也不再需要给成员变量加上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;
    }
}

在显式歧义(即,描述成员和描述形参)的情况下,我们使用语言构造来引用成员变量:this。

m_前缀通常用于成员变量——我认为它的主要优点是有助于明确区分公共属性和支持它的私有成员变量:

int m_something

public int Something => this.m_something; 

对于备份变量有一个一致的命名约定是有帮助的,m_前缀是一种实现方式——在不区分大小写的语言中是有效的。

这有多有用取决于你所使用的语言和工具。具有强大的重构工具和智能感知功能的现代ide不太需要这样的约定,而且这当然不是做到这一点的唯一方法,但在任何情况下都值得注意这种实践。

为了完成当前的答案,因为这个问题不是特定于语言的,一些c项目使用前缀m_来定义特定于文件的全局变量,使用g_来定义作用域大于所定义文件的全局变量。 在这种情况下,使用前缀m_定义的全局变量应该定义为静态变量。

请参阅EDK2 (UEFI开源实现)编码约定,了解使用该约定的项目示例。

还有人提到它的意思是一个阶级成员。Qt是一个流行的c++框架,它使用了这个符号,所以很多c++ GUI教程都使用m_。你可以看到他们几乎所有的例子都使用m_作为类成员。就我个人而言,我使用m_,因为它比这个->短,感觉紧凑。

洛克希德·马丁公司使用了一个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*
}

为了它的价值而接受它。