Должен ли конструктор инициализировать все члены данных класса?
у меня такая ситуация:
class A {
public:
A() : n(0) {}
private:
int n;
int m;
}
в логике приложения просто нет смысла инициализировать m
в конструкторе. Однако Eclipse предупреждает меня, что конструктор оставляет m
неинициализированной. Я не могу запустить код в другом месте. Предупреждение:
элемент " m " не был инициализирован в этом конструкторе
Итак, c++ поощряет нас инициализировать все члены данных в конструкторе или это просто Логика в Eclipse?
5 ответов
должен ли конструктор инициализировать все члены данных класса?
Это было бы хорошей практикой.
Итак, c++ поощряет нас инициализировать все члены данных в конструкторе?
это не требуется стандартом c++. Пока вы инициализируете все переменные до их использования, ваша программа в этом отношении правильна.
или это просто логика Eclipse?
вполне вероятно. Ни версии g++, ни clang, которые я тестировал, не предупреждают об этом, когда все предупреждения включены. Логика может быть или не быть основана на высокий стандарт кодирования целостности c++ 12.4.2 или какой-либо другой стандарт кодирования или руководство по стилю.
C++ не требует инициализации атрибутов в конструкторе, за исключением атрибутов const, где значение должно быть определено в списке инициализации.
однако, очевидно, что хорошей практикой является инициализация всех атрибутов в конструкторе. Я не могу подсчитать, сколько ошибок я встретил из-за неинициализированной переменной или атрибутов.
наконец, каждый объект должен постоянно находиться в последовательный состояние, которое включает оба публичные (доступные) атрибуты, а также частные атрибуты. Оптимизация не должна быть причиной сохранения объекта непротиворечивым.
для полноты предупреждение поступает из анализа кода C/C++. В частности проблема Potential Programming Problems
/ Class members should be properly initialized
чтобы изменить параметры анализа кода (в этом случае я рекомендую для каждого проекта), измените свойства проекта. Вы можете отключить все предупреждение или отключить его только для файлов, нарушающих условие предупреждения.
Что касается сравнения CDT с GCC или CLang, это, по-видимому, случай, когда дополнительный код анализ выполняется CDT по сравнению с тем, что доступно от компиляторов. Конечно, этого следует ожидать, так как анализ кода CDT' remit больше, чем у компилятора.
PS, Если вы готовы к этому, вы можете прочитать реализацию этого особый checker.
полностью согласен со всеми ответами и комментариями. Нет абсолютно никакой необходимости инициализировать элемент по умолчанию, когда он не нужен. Вот почему C / C++ никогда не инициализирует встроенные типы как члены или автоматические переменные-потому что это будет препятствовать производительности. Конечно, это не проблема, когда вы создаете свой объект/переменную один раз (поэтому статика инициализируется по умолчанию), но для чего-то, что происходит в узком цикле, инициализация по умолчанию может быть полезной наносекунды.
единственным исключением из этого правила, на мой взгляд, будут указатели (если у вас в коде есть необработанные указатели). Необработанные указатели должны быть инициализированы NULL, так как наличие недопустимого указателя является прямым способом неопределенного поведения.
Как уже было сказано, вы должны всегда инициализировать указатели и, конечно, объекты const являются обязательными.
на мой взгляд, вы не должны инициализировать, когда это не нужно, но хорошо проверять все не инициализированные конструктором переменные время от времени, потому что они являются источником очень частых и трудно найти ошибки.
Я запускаю Cppcheck каждые несколько месяцев. Это дает мне более ста "ложных" предупреждений, таких как "переменная-член" foo:: bar " не является инициализируется в конструкторе."но время от времени он обнаруживает некоторые реальные ошибки, поэтому это того стоит.