非静态数据模因的使用无效

Invalid use of non-static data memeber

本文关键字:无效 静态 数据      更新时间:2023-10-16

我在A.h中有以下代码:

class A
{
public:
    ...
private:
    ...
    const int X = 1;
    float Y[X];
    ...
};

如果项目中只包含头A.h,则编译良好。但是,如果我在A.cpp中包含A.h,它会给我以下奇怪的错误:

警告:非静态数据成员初始值设定项仅可用于-std=c++11或-std=gnu++11[默认启用]

错误:非静态数据成员"A::X"的使用无效

错误:从这个位置

即使我更改const int X = 1;(尽管我需要它作为一个常量参数),也不会有任何变化。

p.s.如果有意义的话,我使用的是Qt 5.1

p.s.s.实际上使其成为static修复了错误。但为什么我必须这样做?

第一个问题是,您使用的是旧版本的C++,该版本不允许在声明中初始化非静态(即每个对象而不是每个类)成员。您可以根据C++11进行编译(如错误消息所示);或者在构造函数中初始化它;或者将其设为static,如果您不需要为创建的每个对象指定单独的值。

第二个问题是数组大小必须是编译时常数。非静态成员const或其他成员不符合要求。原则上,它在不同的对象中可能有不同的值(即使在声明中这样初始化,它也可能被一个或多个构造函数覆盖),因此没有编译时值。静态成员确实具有固定值,因此如果值可用,则可以用作数组大小。

您的意图是在类中有一个constant变量。

现在这个类被用来创建许多对象。实际上,类应该允许每个对象对const数据成员具有不同的const值,因此不能在类内初始化const成员。

类成员内部的const表示该值在对象的整个生命周期内是恒定的。

这就是为什么存在一个称为constructor initialization list的特殊初始化点,而不允许在构造函数中进行初始化。

现在,如果允许您在构造函数中初始化const成员,那么您可以在构造函数本身中多次重新分配它,这表达了const的含义(也就是说,分配一次,始终保持不变)。

因此,const成员的初始化应该在构造函数之前进行,这在初始化列表中完成。如果需要,这将为不同对象提供具有不同值的const成员。

此外,请注意,构造函数i(ii)中的初始化形式用于在进入构造函数之前初始化数据成员

class A
{
    const int i;
    public:
       A(int ii): i(ii)
       {
          // i  = 5; Can't do this since i is `const`
       }
};

话虽如此,如果您希望所有对象共享相同的const值,那么您可以使用其他答案中指出的static const限定符。

正如Mike Seymour所指出的,对于数组的分配或初始化const变量,您需要有多个时间常数,但类内的consts不会给您提供编译时间常数,因此您必须使用static const限定符,使其成为编译时间常数。

您希望在A的构造函数初始化列表中初始化X,因为它是A:的non-static const成员

class A {
    const int X;
public:
    A() : X(1) {
        // ...
    }
    // ...

也就是说,从类A实例化的每个对象都有一个名为Xint成员(这是non-static的部分,即它不是类的成员),即const(它不能被修改或重置,所以你必须在构造函数初始化列表中初始化它,而不是在构造函数体中初始化它)。

这就是简单的

  • 静态常量int X=1
  • 枚举{X=1};//穷人constexpr

这是罪魁祸首

    float Y[X];

由于您试图用Y的名称声明一个大小为X的浮点数组,但它是类的非静态私有成员。

因此,X将在符号表中,但在上述行的编译过程中无法访问相关值,因此会出现警告和错误。