初始化静态成员使编译工作......但是为什么

Initializing static member makes compilation work... but why

我有 3 个文件:

main.cpp -

#include "test.hpp"

int main(void)
{
    test x;
    return (1);
}

test.hpp -

#ifndef TEST_HPP
#define TEST_HPP

class test
{
    static int a;

public:
    void    func(void);
};

#endif

test.cpp -

#include "test.hpp"

int test::a = 0; // removing this line makes compilation fail

void    test::func(void)
{
    a--;
}

我编译时使用:clang++ *.cpp -I .,我的目录中只有这 3 个文件。

编译失败信息为:

Undefined symbols for architecture x86_64:
  "test::a", referenced from:
      test::func() in test-8bbfc4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

根据我的理解:

int   test::a = 0; // removing this line makes compilation fail

只是将静态成员 a 初始化为 0,因为它已经是 0 实际上没有任何意义。

为什么这会对编译产生影响?

was just initializing the static member a to 0

不,这不仅仅是初始化,它是static data member的定义。没有它,您将得到如您所见的 link 错误。

The declaration inside the class body is not a definition...

顺便说一句:Constant static members* and inline static members(自 C++17 起)可以在 class 定义中定义。


*注意当一个const non-inline non-constexpr静态数据成员被odr-used时,仍然需要在命名空间范围内定义,但是它不能有初始值设定项。