![](/img/trans.png)
[英]Why can't a static constexpr member variable be passed to a function?
[英]why i can't call a static member variable in an static member function like this?
大家! 有一个类似于以下的代码段: 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;
}
当我单击“构建”按钮时,输出消息是
错误LNK2001:无法解析的外部符号“ public:static int Test :: b”(?b @ Test @@ 2HA)1> B:\\ PROGRAMPROJECT \\ visual 2015 pro \\ testcase \\ testcase \\ x64 \\ Debug \\ testcase.exe:致命错误LNK1120:1个未解决的外部元件
但是,当我这样更改代码位置时:
#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;
}
确实有效! 我不知道为什么?有人可以帮助我吗? 我的IDE是vs pro 2015 + Windows10。
其他答案集中于解决问题,而不是回答“为什么”部分。
当您在类主体中定义一个函数时,它会自动被认为是inline
函数,并且任何数量的翻译单元(例如C ++源代码)都可以定义它们。 那就是您通常在头文件中定义函数的方式-主体的函数将include
在多个源中。
当您仅在类主体中声明一个函数而在外部定义它时,该函数不会自动标记为inline
,这意味着包含此定义的每个翻译单元都会生成自己的强符号。 在这种情况下,通常会将头文件中的声明与关联的源文件中的实现解耦,否则会出现多个符号错误。 (即,如果标头中包含非内联定义,则包含它们的每个源都会生成这些符号,并且链接器会感到困惑,因为它会看到同一非内联函数的多个版本来自不同的源)
现在,当您定义静态成员变量时,除非它是内联的,否则还必须与翻译单元关联。 类似于声明extern
全局变量,该变量也必须在某处定义。 对于您的情况,您只需添加:
int Test::b;
将定义与声明解耦时,这一点更为重要。 假设您有两个文件:
测试文件
class Test {
public:
static int b ;
static void test();
};
测试文件
#include "Test.hpp"
int Test::b;
void Test::test()
{
b = 3;
cout << b<<endl;
}
这些符号(在这种情况下,是全局变量Test::b
和函数Test::test
)与文件Test.cpp相关联,并且仅生成一次。 您可以在任意数量的源文件中包含Test.hpp,并且不会生成其他符号。
您已声明Test::b
但尚未定义它。 将此行添加到您的代码中(Test类之外)
int Test::b;
您也可以根据需要提供初始值
int Test::b = 123;
如何解决
使用C++17
您可以内联静态变量,从而无需在类外部定义它。
static inline int i = 0; // I would also initialize it to zero, just to be sure
如果您不能使用C++17
,则必须定义
int Test::b = 0; // Again I would also initialize it to zero, just to be sure
课外Test
为什么
当你写
static void test()
{
static int b; // <-- definition is here
b = 3;
cout << b << endl;
}
您可以直接在类中定义函数(这意味着它会自动标记为内联)。 然后,您也可以在那里定义静态变量。 如果它在函数范围之外,则仅是一个声明(除非明确标记为内联,如上所示)。
相反,在其他情况下,它不在函数定义之内,因此您缺少静态变量的定义。
class Test {
public:
static int b ; // <-- only declaration - definition is missing
static void test()
{
b = 3;
cout << b<<endl;
}
};
修复了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;
}
};
修正在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.