Инициализация полей класса
Automatically generated description.
Два дня убил на выявление одной подлой ошибки. Проблема была в том, что на одном компьютере программа работала исправно, а на другом – segmentation fault.
Ошибка возникала по вине неинициализированной переменной (которая представляла собой файловый дескриптор).
А не проявлялась она на одном из компьютеров, по-видимому, из-за различий версий компилятора С++.
Проблема демонстрируется следующим кодом:
class MyClass {
int myField;
public:
MyClass(){}
~MyClass(){}
int getMyField(){return myField;}
};
Создадим два объекта этого класса, один – в куче, другой – в стеке, и выведем поля:
#include <iostream>
int main(){
MyClass *obj = new MyClass();
std::cout << obj->getMyField() << std::endl;
MyClass obj2;
std::cout << obj2.getMyField() << std::endl;
}
Теперь скомпилируем программу в различных версиях компилятора и посмотрим на результаты её выполнения.
$ g++-4.3 main.cpp -o 4.3 && g++-4.4 main.cpp -o 4.4
$ ./4.3 && ./4.4
0
-1217331212
0
134514832
В первом случае результаты одинаковы – поле успешно инициализировано. Второй же случай более интересен. Мы видим, что новая версия компилятора инициализирует переменную положительной константой (вы можете убедиться в этом, несколько раз запуская программу), тогда как в результате компиляции версией 4.3 получаем меняющееся от запуска к запуску значение в неинициализированном поле класса.
<h2>Вывод</h2>
Если вы планируете создавать объекты в стеке – инициализируйте все поля класса. Инициализируйте их в любом случае, так, на всякий случай.
<h2>To read</h2>
<ul>
- [C++ <span class="caps">FAQ</span>. Constructors](http://www.parashift.com/c%2B%2B-faq-lite/ctors.html)
</ul>
<h2>P.S.</h2>
Насколько я знаю, Java и C# не допускает неинициализированных полей.