为什么你_必须_初始化一个C++静态成员变量?

发布于 2024-09-30 11:43:13 字数 787 浏览 0 评论 0原文

我知道您通常从 .cpp 文件中初始化静态成员变量。但我的问题是:为什么你必须这样做?

这是一个例子:

#include <vector>

using namespace std;

class A {
    public:
        static vector<int> x;
};

main() {
    int sz = A::x.size();
}

这会产生编译器错误: undefined reference to 'A::x'

但是,这:

#include <vector>

using namespace std;

class A {
    public:
        static vector<int> x;
};

// Initialize static member
vector<int> A::x;

main() {
    int sz = A::x.size();
}

编译并运行良好。

我可以理解我是否使用默认构造函数以外的其他东西来初始化向量,但我没有。我只想创建一个大小为 0 的向量。当然,任何静态成员都必须在程序初始化时分配内存,那么为什么编译器不只使用默认构造函数呢?

I know that you generally initialize a static member variable from within a .cpp file. But my question is: why do you have to?

Here's an example:

#include <vector>

using namespace std;

class A {
    public:
        static vector<int> x;
};

main() {
    int sz = A::x.size();
}

This gives a compiler error: undefined reference to 'A::x'

However, this:

#include <vector>

using namespace std;

class A {
    public:
        static vector<int> x;
};

// Initialize static member
vector<int> A::x;

main() {
    int sz = A::x.size();
}

compiles and runs fine.

I can understand if I was initializing the vector using something other than the default constructor, but I'm not. I just want a vector of size 0 created. Surely, any static members will have to be allocated memory on program initialization, so why doesn't the compiler just use the default constructor?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

故乡的云 2024-10-07 11:43:13

这不是关于初始化的问题,而是关于定义的问题。
或者更准确地说:它是关于知道哪个编译单元(.cpp)将保存该对象(必须在某个地方唯一定义)

因此,所需要的只是将定义放在某处 strong>,在一个独特的地方,即cpp,让编译器知道当调用类的静态对象时,它是在那里定义的,而不是在其他地方。 (如果您尝试在标头中定义静态,则包含此标头的每个 cpp 都会有一个定义,从而无法知道应该在哪里定义它 - 并且如果您需要使用它,则需要手动初始化)

That's not about initialization, it's about definition.
Or more precisely : it's about knowing which compilation unit (.cpp) will hold the object (that have to be uniquely defined SOMEWHERE)

So, what's needed is simply to put the definition somewhere, in a unique place, that is a cpp, to let the compiler know that when the class's static object is called, it's defined there and nowhere else. (if you try to define your static in a header, each cpp including this header will have a definition, making impossible to know where it should be defined - and manually initialized if it's required for you use)
.

北恋 2024-10-07 11:43:13

您是从单个编译单元的角度来看待它的。

但该语言必须假设可能存在多个编译单元。那么现在静态对象是在哪个编译单元中创建的呢?基本上不允许编译器做出该决定,而工程师必须做出决定。

You are looking at it from the point of a single compilation unit.

But the language has to assume there can potentially by multiple compilation units. So now in which compilation unit is the static object created? Basically the compiler is not allowed to make that decision and the engineer must make the decision.

赴月观长安 2024-10-07 11:43:13

对“A::x”的未定义引用不是编译器错误;而是编译器错误。这是一个链接器错误。这意味着在链接在一起形成程序的任何翻译单元中都找不到 A::x 的定义。静态成员变量具有外部链接,并且必须在一个翻译单元中定义。任何具有外部链接的内容都不会具有编译器生成的定义,除非您编写一个定义。

undefined reference to 'A::x' isn't a compiler error; it's a linker error. It means that a definition of A::x can't be found in any of the translation units that are being linked together to form your program. Static member variables have external linkage and must be defined in exactly one translation unit. Anything with external linkage will not have a definition generated by the compiler unless you write one.

稀香 2024-10-07 11:43:13

你所说的初始化就是定义。您需要在某处定义静态成员。类内部的部分只是一个声明。

这主要是因为在标头中包含定义会导致巨大的问题(因为您无法将该标头包含到多个翻译单元中而不导致多个定义)。

What you call initialization is definition. You need to define the static member somewhere. The part inside the class is just a declaration.

This is mostly because having a definition inside the header would cause huge problems (since you couldn't include that header into more then one translation unit without causing multiple definitions).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文