объявление константного экземпляра класса - PullRequest
36 голосов
/ 13 января 2011

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

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?

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

РЕДАКТИРОВАТЬ: пожалуйста, не стесняйтесь закрыть его, если это глупо ...

Ответы [ 4 ]

47 голосов
/ 13 января 2011

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

foo x;

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

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

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

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

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

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

6 голосов
/ 13 января 2011

Сообщение об ошибке в ситуации пустого класса - известная проблема, о которой сообщается как проблема # 253 .

1 голос
/ 13 января 2011

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

const foo f={};

или

const foo f(());

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

1 голос
/ 13 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...