无法设置静态对象字段的值(错误 LNK2001:未解析的外部符号)

2021-12-31 00:00:00 static compiler-errors c++

我有一段看似简单直接的代码,它是我在编写的游戏中遇到的问题的简化版本.我试图将一个类中的静态字段设置为我的主要方法中的另一个值.但是这段代码不会,我不明白为什么.

我收到错误

<块引用>

1>Source.obj : error LNK2001: 未解析的外部符号public:静态类 A * B::a" (?a@B@@2PAVA@@A)

A 类{上市:一个(){}};B级{上市:静态 A* a;};int main(){B::a = 新 A;}

我必须在类之外定义我的静态类成员才能链接它的规则是什么?

解决方案

来自您的评论

<块引用>

但是定义它的规则是什么?

来自 c++ 参考,它说

<块引用>

定义和 ODR

定义是完全定义由声明引入的实体的声明.每个声明都是一个定义,除了以下内容:

...

<块引用>

  1. 在类定义中声明静态数据成员

struct S {//定义 S国际n;//定义 S::n静态 int i;//声明,但没有定义 S::i};int S::i = 0;//定义并初始化 S::i

作为附加参考,您还可以在此处查看维基百科,一个定义规则


我终于找到了当前(2014 年 6 月 2 日)最新的免费标准参考(我认为目前发布的标准的副本大约需要 30 美元):

<块引用>

§ 9.4.2

2 静态数据成员在其类定义中的声明不是定义,可能是不完整的cv 限定的 void 以外的类型.静态数据成员的定义应出现在命名空间中包含成员类定义的范围.在命名空间范围的定义中,静态的名称数据成员应使用 :: 运算符通过其类名进行限定.中的初始化表达式静态数据成员的定义在其类的范围内

I have seemingly simple and straightforward segment of code that is a simplified version of a problem I have been having in a game I am writing. I am trying to set a static field in one class to another value from my main method. However this code will not and I don't understand why.

I get the error

1>Source.obj : error LNK2001: unresolved external symbol "public: static class A * B::a" (?a@B@@2PAVA@@A)

class A
{
public:
    A()
    {

    }
};

class B
{
public:
    static A* a;
};

int main()
{
    B::a = new A;
}

What is the rule saying that I have to define my static class member outside the class to get it linked?

解决方案

As from your comment

but what is the rule that defines that?

From the c++ reference it says

Definitions and ODR

Definitions are declarations that fully define the entity introduced by the declaration. Every declaration is a definition, except for the following:

...

  1. Declaration of a static data member inside a class definition

struct S {    // defines S
    int n;        // defines S::n
    static int i; // declares, but doesn't define S::i
};
int S::i = 0; // defines and initializes S::i

As an additional reference you can also check here Wikipedia, One Definition Rule


I finally found the current (2nd June 2014) latest freely available standard reference (a copy of the currently released standard is available for about 30$ I think):

§ 9.4.2

2 The declaration of a static data member in its class de?nition is not a de?nition and may be of an incomplete type other than cv-quali?ed void. The de?nition for a static data member shall appear in a namespace scope enclosing the member’s class de?nition. In the de?nition at namespace scope, the name of the static data member shall be quali?ed by its class name using the :: operator. The initializer expression in the de?nition of a static data member is in the scope of its class

相关文章