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

Должен ли конструктор инициализировать все члены данных класса?

У меня такая ситуация:

class A {
public:
  A() : n(0) {}
private:
  int n;
  int m;
}

В логике приложения просто нет смысла инициализировать m в конструкторе. Однако Eclipse предупреждает меня, что конструктор оставляет m неинициализированным. Я не могу запустить код где-то еще. Предупреждение:

Член 'm' не был инициализирован в этом конструкторе

Итак, поддерживает ли С++ инициализацию всех элементов данных в конструкторе или это просто логика Eclipse?

4b9b3361

Ответ 1

Должен ли конструктор инициализировать все члены данных класса?

Это будет хорошая практика.

Итак, поддерживает ли С++ инициализацию всех элементов данных в конструкторе?

Это не требуется по стандарту С++. Пока вы инициализируете все переменные до их использования, ваша программа верна в этом отношении.

или это просто логика Eclipse?

Довольно вероятно. Ни g++, ни версии clang, которые я тестировал, не предупреждают об этом, когда все предупреждения включены. Логика может быть или не основываться на стандарте высокой степени целостности С++ 12.4.2 или какой-либо другой стандарт кодирования или руководство по стилю.

Ответ 2

С++ не требует инициализации атрибутов в конструкторе, кроме как в случае атрибутов const, где значение должно быть определено в списке инициализации.

Однако, очевидно, хорошая практика для инициализации всех атрибутов в конструкторе. Я не могу подсчитать, сколько ошибок я встречал из-за не инициализированной переменной или атрибутов.

Наконец, каждый объект должен постоянно находиться в состоянии согласованный, который включает как общедоступные (доступные) атрибуты, так и частные атрибуты. Оптимизация не должна служить основанием для непротиворечивости объекта.

Ответ 3

Для полноты, предупреждение приходит из анализа кода C/С++. В частности, задача Potential Programming Problems/Class members should be properly initialized

Чтобы изменить параметры анализа кода (в этом случае я рекомендую для каждого проекта), отредактируйте свойства проекта. Вы можете отключить все предупреждение или отключить его только файлы, которые нарушают условие предупреждения.

показать предупреждение

Что касается сравнения CDT с GCC или CLang, это, по-видимому, случай, когда CDT делает дополнительный анализ кода по сравнению с тем, что доступно от компиляторов. Разумеется, это следует ожидать, так как пересмотр CDT Code Analysis больше, чем у компилятора.

PS. Если вы этого хотите, вы можете прочитать реализацию этой конкретной проверки.

Ответ 4

Полностью не согласен со всеми ответами и комментариями. Абсолютно нет необходимости по умолчанию инициализировать член, когда он не нужен. Вот почему C/С++ никогда не инициализирует встроенные типы как члены или автоматические переменные, потому что это будет препятствовать производительности. Конечно, это не проблема, когда вы создаете свой объект/переменную один раз (почему статика инициализируется по умолчанию), но для чего-то, что происходит в жестком цикле, инициализация по умолчанию может иметь ценные наносекунды.

Единственное исключение из этого правила, на мой взгляд, было бы указателем (если в вашем коде есть обычные указатели). Необработанные указатели должны быть инициализированы NULL, так как неправильный указатель является прямым способом поведения undefined.

Ответ 5

Как уже было сказано, вы всегда должны инициализировать указатели, и, конечно, объекты const обязательны.

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

Я запускаю Cppcheck каждые несколько месяцев. Это дает мне более ста "ложных" предупреждений вроде "Member variable" foo:: bar 'не инициализируется в конструкторе ". но время от времени он обнаруживает некоторые реальные ошибки, поэтому он вполне достоин этого.