3

我在 Ah 中有以下代码:

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

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

...警告:非静态数据成员初始化器仅适用于 -std=c++11 或 -std=gnu++11 [默认启用]

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

...错误:从这个位置

即使我改变const int X = 1;了(虽然我需要它作为一个常量参数),也没有任何改变。

ps 如果有意义的话,我使用的是 Qt 5.1

pss 实际上使它static修复了错误。但为什么我必须这样做?

4

5 回答 5

5

The first problem is that you're compiling against an old version of C++, which didn't allow non-static (that is, per-object rather than per-class) members to be initialised in their declaration. You can either compile against C++11 (as the error message suggests); or initialise it in the constructor; or make it static, if you don't need a separate value for each object you create.

The second problem is that an array size must be a compile-time constant. A non-static member, const or otherwise, doesn't fit the bill. In principle, it could have different values in different objects (even if it's initialised in the declaration like that, it could be overridden by one or more constructors), so there is no compile-time value. A static member does have a fixed value, so that can be used as an array size, if the value is available.

于 2013-08-22T17:13:00.300 回答
3

Your intention is to have a constant variable inside the class.

Now this class is used to create many objects. Practically the class should allow each object to have different const value for the const data member , thus you can't initialize const members inside class.

const inside class members means the value is constant throughout the life time of the object.

That is why there exist a special initialization point called constructor initialization list rather than allowing the initialization in the constructor.

Now, if you're allowed to initialize the const member inside the constructor then you could re-assign it multiple times within the constructor itself which voilates the meaning of const(which means, assigned once and remains same throughout).

Hence the initialization of the const members should happen before the constructor, which is done in the initialization list. This gives you const members with different values for different objects if you want.

Also, note that the form of initialization in the constructor i(ii) is used to initialize the data members before entering the constructor

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

Having said that, if you want all the object to share the same const value then you can use static const qualifier as pointed in others answers.

Also as Mike Seymour pointed out, for allocation of arrays or initializing const variables you need to have comiple-time constants, but consts inside class doesn't give you compile time constants, hence you will have to use the static const qualifier which makes it a compile time constant.

于 2013-08-22T17:14:38.253 回答
2

您想X在构造函数初始化列表中进行初始化,A因为它是以下non-static const成员的成员A

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

也就是说,从类实例化的每个对象A都有一个int名为Xnon-static即它不是类的成员的部分)的成员const(它不能被修改或重置,因此您必须在构造函数初始化列表中对其进行初始化,不是构造函数体)。

于 2013-08-22T16:37:45.417 回答
0

这很简单

  • 静态常量 int X = 1;
  • 枚举 { X = 1 }; // 可怜的人 constexpr
于 2013-08-22T16:38:50.543 回答
0

这是你的罪魁祸首

    float Y[X];

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

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

于 2013-08-22T17:04:32.793 回答