简体   繁体   English

为什么我不能在这样的静态成员函数中调用静态成员变量?

[英]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 有一个类似于以下的代码段: 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 错误LNK2001:无法解析的外部符号“ public:static int Test :: b”(?b @ Test @@ 2HA)1> B:\\ PROGRAMPROJECT \\ visual 2015 pro \\ testcase \\ testcase \\ x64 \\ Debug \\ testcase.exe:致命错误LNK1120:1个未解决的外部元件

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. 我的IDE是vs pro 2015 + Windows10。

The other anwers focus on solving the problem, instead of answering the "why" part. 其他答案集中于解决问题,而不是回答“为什么”部分。

When you define a function within class body, it is automatically considered to be inline and any number of translation units (think about C++ sources) may define them. 当您在类主体中定义一个函数时,它会自动被认为是inline函数,并且任何数量的翻译单元(例如C ++源代码)都可以定义它们。 That's the way you would normally define functions within header file - a function that's body will be include d in multiple sources. 那就是您通常在头文件中定义函数的方式-主体的函数将include在多个源中。

When you only declare a function within class body, but define it outside, it is not automatically marked as inline , which means that each translation unit that contains this definition will generate its own strong symbol. 当您仅在类主体中声明一个函数而在外部定义它时,该函数不会自动标记为inline ,这意味着包含此定义的每个翻译单元都会生成自己的强符号。 In this case, you usually decouple the declaration in a header file, from implementation in an associated source file, otherwise you'd get multiple symbol errors. 在这种情况下,通常会将头文件中的声明与关联的源文件中的实现解耦,否则会出现多个符号错误。 (ie if you have non-inline definitions in headers, each source that include them generates those symbols and linker gets confused because it sees multiple versions of the same non-inline function coming from different sources) (即,如果标头中包含非内联定义,则包含它们的每个源都会生成这些符号,并且链接器会感到困惑,因为它会看到同一非内联函数的多个版本来自不同的源)

Now, when you define a static member variable, unless it's inline, it also must be also associated with a translation unit. 现在,当您定义静态成员变量时,除非它是内联的,否则还必须与翻译单元关联。 It's similar to declaring an extern global variable, that also has to be defined somewhere. 类似于声明extern全局变量,该变量也必须在某处定义。 In your case, you should simply add: 对于您的情况,您只需添加:

int Test::b;

It's more important when you decouple definition from declaration. 将定义与声明解耦时,这一点更为重要。 Say, you have two files: 假设您有两个文件:

Test.hpp 测试文件

class Test {
public:
    static int b ;
    static void test();
};

Test.cpp 测试文件

#include "Test.hpp"
int Test::b;
void Test::test()
{
    b = 3;
    cout << b<<endl;
}

The symbols (in this case, the global variable Test::b and the function Test::test ) are associated with the file Test.cpp and are generated exactly once. 这些符号(在这种情况下,是全局变量Test::b和函数Test::test )与文件Test.cpp相关联,并且仅生成一次。 You may include Test.hpp in any number of source files and no additional symbols will be generated. 您可以在任意数量的源文件中包含Test.hpp,并且不会生成其他符号。

For referece, see https://en.cppreference.com/w/cpp/language/static 有关参考,请参阅https://en.cppreference.com/w/cpp/language/static

You've declared Test::b but you haven't defined it. 您已声明Test::b但尚未定义它。 Add this line to your code (outside of the Test class) 将此行添加到您的代码中(Test类之外)

int Test::b;

you can give an initial value as well if you wish 您也可以根据需要提供初始值

int Test::b = 123;

How to solve it 如何解决

Using C++17 you can inline the static variable which removes the need to define it outside the class. 使用C++17您可以内联静态变量,从而无需在类外部定义它。

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 如果您不能使用C++17 ,则必须定义

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

outside of class Test 课外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 修复了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 修正在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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么不能将静态constexpr成员变量传递给函数? - Why can't a static constexpr member variable be passed to a function? 静态成员变量可以调用非静态成员函数吗? - Can a static member variable call non-static member functions? How can I call a non-static member function of a class from a static member function of another class? - How can I call a non-static member function of a class from a static member function of another class? 为什么不能在main()里面定义一个static的成员变量? - Why can't a static member variable be defined inside main()? 想要一个静态成员函数来调用同一类的成员变量 - Want a static member function to call a member variable of the same class 为什么静态成员函数不能有cv-qualifier? - Why can't a static member function have a cv-qualifier? 为什么不能在此成员函数中设置此成员变量? - Why can't I set this member variable in this member function? 为什么我不能推断静态成员函数是否存在 - Why can I not deduce if the static member function exists 为什么我不能在.hpp 中定义一个 static class 成员字段? - Why can't I define a static class member field in .hpp? 为什么静态成员函数不能恒定? - Why can't static member functions be constant?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM