我是c ++的新手,正在尝试使用类和静态变量。
我已经找到了使代码运行的解决方案,但是我不确定为什么可以运行,为什么我以前的方法不起作用
#include <iostream>
using namespace std;
class Person {
static int id;
public:
void createPerson() {
id++;
cout << id << endl;
}
};
int Person::id = 0;
int main() {
Person Person1;
Person Person2;
Person1.createPerson();
Person2.createPerson();
}
我想知道为什么我必须在类外声明id的值。以及为什么我不能拥有类似的东西。
class Person {
static int id = 0;
public:
void createPerson() {
id++;
cout << id << endl;
}
};
答案 0 :(得分:4)
static
数据成员不是对象的一部分,因此您需要通过提供该定义来明确告诉编译器将其存储在哪个转换单元中。
请注意,可以在头文件中定义类模板的静态数据成员。
在C ++ 17中,可以将static
数据成员声明为inline
,这样就不需要行外定义。
答案 1 :(得分:2)
添加inline
关键字即可完成这项工作。只需将行更改为:
static inline int id = 0;
另一种可能是,但仅当您的值恒定时,才可以这样声明:
static inline constexpr int id = 0;
这是声明全局常量而不是使用#define
的首选方法。
答案 2 :(得分:0)
在类定义中,静态数据成员被声明为bur未定义。因此,您甚至可以在类定义内的静态数据成员的声明中使用非完整类型。
例如
struct A
{
static int a[];
};
int A::a[10];
在此示例中,类定义中数据成员a的声明具有不完整的数组类型(数组的元素数未知)。
从C ++ 17开始,您可以将静态数据成员声明为嵌入式成员。例如
class Person {
inline static int id = 0;
public:
void createPerson() {
id++;
cout << id << endl;
}
};
在这种情况下,您可以在类定义内的声明中对其进行初始化。
否则,只有在声明为具有整数类型并且具有限定符const
或指定符constexpr
的情况下,才可以在类定义中初始化静态数据成员(在最后一种情况下为静态数据)成员将是内联声明。
但是,如果将静态数据成员声明为const对象,则必须在类外定义它,例如,如果您尝试获取静态数据成员的地址。例如此代码无效
#include <iostream>
using namespace std;
class Person {
const static int id = 0;
public:
void createPerson() {
cout << &id << endl;
}
};
int main()
{
Person Person1;
Person Person2;
Person1.createPerson();
Person2.createPerson();
}
由于已获取静态数据成员的地址,因此您必须定义静态数据成员。
#include <iostream>
using namespace std;
class Person {
const static int id = 0;
public:
void createPerson() {
cout << &id << endl;
}
};
const int Person::id;
int main()
{
Person Person1;
Person Person2;
Person1.createPerson();
Person2.createPerson();
}
该程序将编译。