为什么静态成员函数只能在类定义中声明为static而不是在自己的定义中?

mr_*_*r_T 14 c++ static member-functions

在屏幕上实现创建/更新框的类时,我想添加一个静态成员函数,确保当前没有可见的框重叠(将其信息从静态指针数组传递到所有当前可见的框)

我的初始代码具有以下结构:

class Box
{
public:
    // ...
    static void arrangeOverlappingBoxes();
};

static void Box::arrangeOverlappingBoxes()
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我很惊讶这产生了一个错误C2724:'static'不应该用在文件范围定义的成员函数上.

通过一些试验,谷歌和错误,我发现我的函数定义应该丢失关键字static,即它应该是

void Box::arrangeOverlappingBoxes()
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但我不知道这背后的理由是什么.在类定义及其自己的定义中,它的声明具有不同的函数头似乎是如此不对称和令人困惑.这有什么理由吗?

Mic*_*CMS 10

您的类定义(在头文件中)将为函数提供必要的任何项目:

  • 静态的
  • 内联
  • 虚拟

考虑到每个其他对象将使用.h查看您的类定义,那么在那里定义这些属性是有意义的.

此外,类中的每个函数都将在派生类中确定它的属性(例如,您只需要在基类中声明析构函数virtual,每个后续继承都将析构函数作为虚函数).

在您的实现主体中重新声明这些属性是没有意义的.

必须在.h和.cpp文件中声明函数属性实际上会导致所有问题.想象一下这种情况:在.h文件中声明一个虚函数,在.cpp文件中声明为static.编译器将使该功能发生什么?虚拟还是静态?(或者更可能是编译错误,但编译器错误只会促使您在.cpp文件中匹配标头中的声明.您不能根据"静态"或"虚拟"重载函数).

  • 感谢您的回答,但我仍然没有明白这一点。编译器可以被编程为在属性相同的情况下进行编译,就像参数应该相等一样(实际上,Java 语法要求它是这样)。那你为什么说它没有意义呢?以我的拙见,这很有意义:如果您只查看您的 cpp 文件(假设您的类定义在标题中),您会立即看到该函数是静态的,并且没有,例如,没有 this 指针无需查看头文件。 (2认同)
  • 谢谢,命名约定确实是我将如何处理它,但我还没有完全相信在声明和定义中要求相等的签名(名称、参数和属性)会适得其反。它在最近的语言中以不同的方式实现这一事实诱使我将其视为 C++ 怪癖。 (2认同)