如何在派生类的函数中使用基类的静态const字段作为数组的大小?

时间:2019-01-27 13:09:53

标签: c++ static initialization const

我有一个阶级的阶层。这些类的方法可能会创建相同大小的临时静态数组。我想将大小设置为基类的static const字段。

我将该字段的声明放在一个可听文件中,并在源文件中对其进行了初始化。使用GCC 4.3进行编译时,此方法不会出现问题,但对于VS编译器,则失败。

Base.h

class Base
{
public:
    virtual void function();

protected:
    static const int size;
};

Base.cpp

#include "Base.h"

const int Base::size = 128;

void Base::function()
{
    int array[size];
}

Derived.h

#include "Base.h"

class Derived : public Base
{
    void function();
};

Derived.cpp

#include "Derived.h"

void Derived::function()
{
    int array[size];
}

Main.cpp

#include "Derived.h"

int main()
{
    Base* object = new Derived();
    object->function();
    return 0;
}

我希望size将在Base.cpp中初始化,并在Derived.cpp中被视为const。但是它仅适用于GCC编译器。 Visual Studio显示以下错误消息:

错误C2131:表达式的计算结果不为常量

注意:失败是由非恒定参数或对非恒定符号的引用引起的

注意:请参阅“大小”的用法

2 个答案:

答案 0 :(得分:3)

常量变量只能在遇到常量初始化后才能使用(并且是常量初始化程序)。 Base::size尚未在Derived.cpp中初始化,因此无法在常量表达式(例如数组的长度)中使用:程序格式错误。

  

如何在派生类的函数中使用基类的静态const字段作为数组的大小?

初始化类声明中的大小,然后将其声明为constexpr。

答案 1 :(得分:1)

如评论中所指出,GCC扩展使此编译成功。通过删除

可以轻松解决该问题。
const int Base::size = 128;

然后将{.h中的Base::size更改为

static constexpr int Base::size = 128;

这确保可以在编译时评估Base :: size。如果您希望对size的值产生更大的影响,可以使用模板:

template <int N>
class Base {
    protected: static constexpr int size = N;
};
通过呼叫

Base<10>::size; // returns 10
Base<128>::size; // returns 128

using my_base = Base<128>;
my_base::size; // returns 128