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

时间:2014-06-01 20:00:15

标签: c++ static compiler-errors

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

我收到错误

  

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

class A
{
public:
    A()
    {

    }
};

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

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

我必须在类外部定义我的静态类成员才能将其链接起来,这是什么规则?

2 个答案:

答案 0 :(得分:5)

从评论

开始
  

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

从它所说的c++ reference

  

定义和ODR

     

定义是完全定义声明引入的实体的声明。除下列内容外,每份声明均为定义:
  ...
  4)在类定义中声明静态数据成员

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

作为附加参考,您还可以在此处查看Wikipedia, One Definition Rule

<强>更新
我终于找到了当前(2014年6月2日)latest freely available standard reference(我认为目前发布的标准的副本大约30美元):

  

§9.4.2

     

2 在类定义中声明静态数据成员不是一个定义,可能是不完整的   除了cv-quali fi ed void之外的类型。静态数据成员的定义应出现在命名空间中   封闭成员类定义的范围。在命名空间范围的定义中,静态的名称   数据成员应使用::运算符通过其类名限定。初始化表达式   静态数据成员的定义属于其类的范围

答案 1 :(得分:-1)

您没有定义静态数据成员。您只在类定义中声明它。添加以下行

A * B::a;

在主要之前。

或者您可以使用operator new初始化它。

A * B::a = new A;

关于你的问题

  

规则是说我必须定义我的静态类成员是什么规则   在课外让它联系起来?

然后根据第9.4.2节C ++标准的静态数据成员的第2段

  

2在类定义中声明静态数据成员是   不是定义,可能是不完整的类型   cv合格的空白。 静态数据成员的定义应   出现在包含成员类定义的命名空间范围内。