Подтвердить что ты не робот

Объявление экземпляра const класса

Скажем, у меня есть класс, определяемый следующим образом:

class foo{};

теперь это вполне приемлемо;

foo f;

Почему это ошибка компилятора? (uninitialized const ‘f’)

const foo f;

Почему мы должны это делать?

const foo f = foo();

Я знаю, почему мы не можем этого сделать.

const foo f(); // though it compiles..

Интересно, что справедливо следующее:

const std::string f;

Итак, что отсутствует в foo?

Я понимаю, что есть три вопроса, и это плохая форма, но я надеюсь, что кто-то сможет прояснить это для меня в один ответ.

EDIT: пожалуйста, не забудьте закрыть его, если это глупо...

4b9b3361

Ответ 1

Ваш класс POD (по сути, потому что он не предоставляет конструктор по умолчанию). Переменные POD не инициализируются после объявления. То есть, это:

foo x;

не инициализирует x значимому значению. Это нужно делать отдельно. Теперь, когда вы объявляете его как const, это может не произойти, потому что вы больше не можете назначать или изменять x.

Рассмотрим эквивалентность int:

int x; // legal
const int y; // illegal

Как вы заметили, вместо foo компилируется std::string. То потому что std::string не является POD. Простым решением вашей дилеммы является предоставление конструктора по умолчанию для foo:

class foo {
public:
    foo() { }
};

Теперь ваш код const foo x; компилируется.

Ответ 2

Возникновение ошибки в пустом классе является известной проблемой и сообщается как issue # 253.

Ответ 3

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

Ответ 4

Я думаю, что есть больше альтернатив. Вы можете сделать

const foo f={};

или

const foo f(());

Const означает, что вы не можете назначить его позже, так что вам нужно его инициализировать. Поскольку вы не определили конструктор по умолчанию, компилятор предполагает, что он должен быть инициализирован вами. std::string имеет конструктор по умолчанию, поэтому он неявно называется компилятором.