【问题标题】:Why can I not set a value for static variable inside the class?为什么我不能在类中为静态变量设置值?
【发布时间】:2020-01-08 05:19:08
【问题描述】:

我是 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;
    }

};

【问题讨论】:

标签: c++ class object methods static


【解决方案1】:

static 数据成员不是对象的一部分,因此您需要通过提供该定义来明确告诉编译器将它们存储在哪个翻译单元中。

请注意,类模板的静态数据成员可以在头文件中定义。

在 C++17 中,static 数据成员可以声明为 inline,因此不需要进行外联定义。

【讨论】:

  • 非常感谢你澄清了很多!
【解决方案2】:

在类定义中,静态数据成员被声明为未定义。因此,您甚至可以在类定义中的静态数据成员声明中使用非完整类型。

例如

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();
}

这个程序将被编译。

【讨论】:

  • 非常感谢您的回复!确实有助于澄清很多概念。
【解决方案3】:

添加inline 关键字就可以了。只需将您的行更改为:

static inline int id = 0;

另一种可能性是,但前提是您的值是恒定的,这样声明它:

static inline constexpr int id = 0;

这是声明全局常量而不是使用#defines 的首选方式。

【讨论】:

  • 由于id 应该递增,constexpr 部分与问题并不真正相关。
  • @MaxLanghof 千万不要错过向学习者提及constexpr 的机会
  • 感谢您的回复!这有助于学习一种新的方法来处理我遇到的这个问题,我现在肯定会做一些调查 constexpr ?
猜你喜欢
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多