При инициализации встроенной переменной типа данных переменная также ДОЛЖНА быть «построена из пыли». Итак, есть ли конструкторы для встроенных типов?
По запросу я перестраиваю свой ответ из пыли.
Мне не особенно нравится эта фраза "Конструкторы строят объекты из пыли". Это немного вводит в заблуждение.
Объект, будь то примитивный тип, указатель или экземпляр большого класса, занимает определенный известный объем памяти. Эта память должна как-то быть выделена для объекта. В некоторых случаях эта резервная память инициализируется. Эта инициализация - это то, что делают конструкторы. Они не выделяют (или не выделяют) память, необходимую для хранения объекта. Этот шаг выполняется до вызова конструктора.
Бывают случаи, когда переменную не нужно инициализировать. Например,
int some_function (int some argument) {
int index;
...
}
Обратите внимание, что index
не было присвоено значение. При вводе в some_function
часть памяти выделяется для переменной index
. Эта память уже существует где-то; это просто отложено или выделено. Так как память где-то уже существует, каждый бит будет иметь какое-то ранее существующее значение. Если переменная не инициализирована, она будет иметь начальное значение. Начальное значение переменной index
может быть 42, или 1404197501, или что-то совсем другое.
Некоторые языки обеспечивают инициализацию по умолчанию, если программист не указал ее. (C и C ++ этого не делают.) Иногда нет ничего плохого в том, чтобы не инициализировать переменную известным значением. Следующим оператором может быть, например, оператор присваивания. Преимущество инициализации по умолчанию состоит в том, что неудачная инициализация переменных является типичной ошибкой программирования. Недостатком является то, что эта инициализация имеет стоимость, хотя обычно крошечная. Эта крошечная стоимость может быть значительной, когда она происходит в цикле с множеством вложений, который критичен ко времени. Отсутствие начального значения по умолчанию соответствует философии C и C ++ - не предоставлять то, о чем программист не просил.
Некоторые переменные, даже не относящиеся к классу, обязательно должны иметь начальное значение. Например, нет способа присвоить значение переменной, имеющей ссылочный тип, за исключением оператора объявления. То же самое касается переменных, которые объявлены постоянными.
Некоторые классы имеют скрытые данные, которые абсолютно необходимо инициализировать. Некоторые классы имеют const
или элементы справочных данных, которые абсолютно необходимо инициализировать. Эти классы должны быть инициализированы или созданы. Не все классы должны быть инициализированы. Класс или структура, которые не имеют каких-либо виртуальных функций, не имеют явно предоставленного конструктора или деструктора и все данные-члены которых являются простыми типами данных, называются обычными старыми данными или POD. Классы POD не нужно создавать.
Итог:
- Объект, будь то примитивный тип или экземпляр очень сложного класса, не "построен из пыли". В конце концов, пыль очень вредна для компьютеров. Они построены из битов.
- Установка или выделение памяти для какого-либо объекта и инициализация этой резервной памяти - две разные вещи.
- В памяти нужно хранить объект, выделенный, а не созданный. Память уже существует. Поскольку эта память уже существует, биты, составляющие объект, будут иметь некоторые ранее существующие значения. Вы, конечно, никогда не должны полагаться на эти ранее существующие значения, но они есть.
- Причина инициализации переменных или членов данных заключается в том, чтобы придать им достоверное, известное значение. Иногда такая инициализация - просто трата процессорного времени. Если вы не просили компилятор предоставить такое значение, C и C ++ предполагают, что упущение является преднамеренным.
- Конструктор для некоторого объекта не выделяет память, необходимую для хранения самого объекта. Этот шаг уже был сделан к тому времени, когда вызывается конструктор. Что делает конструктор - это инициализирует уже выделенную память.
Первоначальный ответ:
Переменная типа примитива не обязательно должна быть "построена из пыли". Память для хранения переменной должна быть выделена, но переменную можно оставить неинициализированной. Конструктор не строит объект из пыли. Конструктор не выделяет память, необходимую для хранения создаваемого объекта. Эта память уже была выделена ко времени вызова конструктора. (Конструктор может инициализировать некоторый элемент данных указателя в память, выделенную конструктором, но биты, занятые этим указателем, уже должны существовать.)
Некоторые объекты, такие как примитивные типы и классы POD, не обязательно инициализировать. Объявите нестатическую переменную примитивного типа без начального значения, и эта переменная будет неинициализирована. То же самое касается классов POD. Предположим, вы знаете, что собираетесь присвоить значение некоторой переменной, прежде чем получите доступ к значению переменной. Вам нужно указать начальное значение? Нет.
Некоторые языки дают начальное значение каждой переменной. C и C ++ нет. Если вы не запрашивали начальное значение, C и C ++ не собираются принудительно устанавливать начальное значение для переменной. Эта инициализация имеет стоимость, обычно крошечную, но она существует.