Search code examples
c++static-membersstatic-functions

why i can't call a static member variable in an static member function like this?


everyone! there is a code snippet like the below: testcase.cpp

#include <string>
#include <iostream>
using namespace std;
class Test {
public:
    static int b ;
    static void test()
    {

        b = 3;
         cout << b<<endl;
    }
};
int main()
{
Test::test();

    return 0;
}

when I click "build" button,the output message is

error LNK2001: unresolved external symbol "public: static int Test::b" (?b@Test@@2HA) 1>B:\PROGRAMPROJECT\visual 2015 pro\testcase\testcase\x64\Debug\testcase.exe : fatal error LNK1120: 1 unresolved externals

but,when i change the code location like this:

  #include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
class Test {
public:
    //static int b;
    static void test()
    {
        static int b;//only change this line
        b = 3;
        cout << b << endl;
    }
};
int main()
{
    Test::test();

    return 0;
}

It does work! I don't know why?Anybody can help me? My IDE is vs pro 2015 + windows10.


Solution

  • How to solve it

    Using C++17 you can inline the static variable which removes the need to define it outside the class.

    static inline int i = 0; // I would also initialize it to zero, just to be sure 
    

    If you cannot use C++17 you will have to define

    int Test::b = 0; // Again I would also initialize it to zero, just to be sure 
    

    outside of class Test

    To the why

    When you wrote

    static void test()
    {
        static int b; // <-- definition is here
        b = 3;
        cout << b << endl;
    }
    

    you defined the function directly in the class (which means it is automatically marked inline). You then also have the definition of your static variable right there. If it is outside of the function scope, it is only a declaration (except if explicitly marked as inline - as shown above).

    In contrast, in the other case it is outside of the function definition and hence your are missing the definition of the static variable.

    class Test {
    public:
        static int b ; // <-- only declaration - definition is missing
        static void test()
        {
            b = 3;
            cout << b<<endl;
        }
    };
    

    Fix spelled out for C++17

    class Test {
    public:
        static inline int b = 0; // <-- now it is defined (and for safety initialized)
        static void test()
        {
            b = 3;
            cout << b<<endl;
        }
    };
    

    Fix spelled out prior to C++17

    #include <string>
    #include <iostream>
    using namespace std;
    class Test {
    public:
        static int b;   // declaration
        static void test()
        {
            b = 3;
            cout << b << endl;
        }
    };
    
    int Test::b = 0;  // definition
    
    int main()
    {
        Test::test();
    
        return 0;
    }