Can't set value of static object field (error

2019-01-02 18:44发布

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?

2条回答
查无此人
2楼-- · 2019-01-02 19:27

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:
...
4) 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

UPDATE:
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 definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class

查看更多
唯独是你
3楼-- · 2019-01-02 19:30

You did not define the static data member. You only declared it in the class definition. Add the following line

A * B::a;

before the main.

Or you could initialize it with using operator new.

A * B::a = new A;

As for your question

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

then according to paragraph #2 of section 9.4.2 Static data members of the C++ Standard

2 The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition.

查看更多
登录 后发表回答