Должен ли конструктор инициализировать все члены данных класса?
У меня такая ситуация:
class A {
public:
A() : n(0) {}
private:
int n;
int m;
}
В логике приложения просто нет смысла инициализировать m
в конструкторе. Однако Eclipse предупреждает меня, что конструктор оставляет m
неинициализированным. Я не могу запустить код где-то еще. Предупреждение:
Член 'm' не был инициализирован в этом конструкторе
Итак, поддерживает ли С++ инициализацию всех элементов данных в конструкторе или это просто логика Eclipse?
Ответы
Ответ 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 'не инициализируется в конструкторе ". но время от времени он обнаруживает некоторые реальные ошибки, поэтому он вполне достоин этого.