Как использовать статическое поле const базового класса в качестве размера массива в функциях производного класса? - PullRequest
0 голосов
/ 27 января 2019

У меня есть иерархия классов.Методы этих классов могут создавать временные статические массивы одинакового размера.Я хочу установить размер как 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 и будет считаться const в Derived.cpp.Но это работает только с компилятором GCC.Visual Studio отображает следующие сообщения об ошибках:

ошибка C2131: выражение не оценивается как постоянное

примечание: сбой был вызван непостоянными аргументами или ссылкой на непостоянный символ

примечание: см. Использование 'size'

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Как отмечено в комментариях, расширение GCC делает эту компиляцию успешной. Проблема легко решается удалением

const int Base::size = 128;

И измените 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
0 голосов
/ 27 января 2019

Постоянная переменная может использоваться в постоянном выражении только после ее инициализации (и является постоянным инициализатором).Base::size не было инициализировано в Derived.cpp, поэтому его нельзя использовать в константном выражении (например, в длине массива): программа некорректна.

Как использоватьстатическое константное поле базового класса как размер массива в функциях производного класса?

Инициализировать размер в объявлении класса и объявить его constexpr.

...