С ++ передает значение const производного класса конструктору базового неожиданного поведения

Я предполагаю, что это довольно просто, но я не смог найти здесь никакого источника.

Производный класс содержит информацию об инициализации, которую необходимо передать базовому классу. В данном случае это резерв памяти.

class Derived: public Base
{
private:
  const unsigned short memorySize= 100;    
public:  
  inline Derived() : Base(memorySize) {}
  void DoStuff();
};

Это с треском проваливается. Я ожидаю, что базовый конструктор вызывается перед производным конструктором, а memorySize назначается только при вызове производного конструктора.

#define memorySize 100

class Derived: public Base
{
private:

public:  
  inline Derived() : Base(memorySize) {}
  void DoStuff();
};

Это работает, как ожидалось.

Мои вопросы: Я предполагаю, что memorySize в первом примере еще не был инициализирован во время вызова базового конструктора, или здесь происходит что-то еще?

Я узнал, что #define для констант нежелательно в C ++, и очень предпочтительно использовать значения const. Является ли это исключением из этого правила или есть более правильный способ справиться с этой ситуацией?


person Micha    schedule 19.11.2019    source источник
comment
Помимо уже опубликованного правильного ответа, да, базовые классы всегда инициализируются до инициализации членов класса, поэтому memorySize не инициализируется при передаче конструктору Base.   -  person Yksisarvinen    schedule 19.11.2019
comment
вы должны включить предупреждения компилятора. Компилятор должен уметь это диагностировать.   -  person eerorika    schedule 19.11.2019
comment
Предупреждения компилятора включены, но я застрял на фреймворке, который помогает мне по минимуму. Но вы правы, мне нужно срочно перейти на другую систему.   -  person Micha    schedule 19.11.2019
comment
@Micha Хм, я проверил. GCC не может диагностировать эту ошибку. Bug clang диагностирует по умолчанию.   -  person eerorika    schedule 19.11.2019
comment
@eerorika с использованием g ++, но с MPLAB X, что может быть неясным в предупреждениях компилятора и т. д. Иногда я больше не понимаю, что происходит, и решаю перезапустить MPLAB, после перезапуска все ошибки компилятора внезапно исчезают, и он компилируется ...   -  person Micha    schedule 19.11.2019


Ответы (1)


Эти два примера совершенно несопоставимы. В первом примере каждый экземпляр Derived получает свою собственную копию memorySize. Как вы уже догадались, конструктор Derived позаботится об этом.

Вы этого совсем не хотите. Для класса есть только одна константа, а не отдельная константа для каждого экземпляра. Это написано как

class Derived: public Base
{
private:
  static const unsigned short memorySize = 100;    
person MSalters    schedule 19.11.2019
comment
Спасибо! Это действительно работает. Но у меня возникает другой вопрос: поскольку константы постоянны, они в любом случае будут одинаковыми во всех экземплярах класса. Почему они не объявляются автоматически статическими? - person Micha; 19.11.2019
comment
@Micha Тот факт, что он постоянный, не означает, что он будет одинаковым для всех объектов этого класса. Вы можете инициализировать его по-разному для каждого отдельного объекта (и после инициализации он будет неизменным для этого объекта). См. пример - person Yksisarvinen; 19.11.2019
comment
@Micha, потому что это только значение по умолчанию, вы все равно можете инициализировать его другим значением в списке инициализации конструктора - person Kaldrr; 19.11.2019