Какие примитивные типы инициализируются по умолчанию в C++?
Когда я использую список инициализации:
struct Struct {
Struct() : memberVariable() {}
int memberVariable;
};
примитивный тип (int
, bool
, float
, enum
, указатель) переменная-член инициализируется по умолчанию. Определено ли значение, которое он получает для реализации, или оно одинаково для всех реализаций?
7 ответов
Вы не правы. Объект не инициализируется по умолчанию, но инициализируется значением. И его значение четко определено
int = 0,
bool = false,
float = 0.0f,
enum = (enum type)0,
pointer = null pointer
pointer to member = null member pointer
Обратите внимание, что ноль находится в диапазоне значений для любого перечисления, даже если он не содержит явного перечислителя с этим значением, поэтому можно инициализировать переменную перечисления этим значением.
В частности, для указателя на члены данных, используемое на практике представление не является полностью нулевыми битами. В так называемом C++ Itanium ABI, используемом, по крайней мере, GCC и Clang, указатель на элементы данных имеет нулевое представление всех битов.
Стандарт говорит (8.5/5
)
По умолчанию инициализировать объект типа T означает:
- если T является типом класса, отличным от POD (раздел 9), вызывается конструктор по умолчанию для T (и инициализация является некорректной, если в ней нет доступного конструктора по умолчанию);
- если T является типом массива, каждый элемент инициализируется по умолчанию;
- иначе объект инициализируется нулями.
,
Инициализировать значение объекта типа T означает:
- если T является типом класса (раздел 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);
- если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса в T инициализируются значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- иначе объект инициализируется нулями
,
Определено ли значение, которое он получает для реализации, или оно одинаково для всех реализаций?
Таким образом, значение будет одинаковым для всех реализаций.
Struct
это не POD тип, так
Struct *a =new Struct; // default initialization
//memberVariable will be initialized to 0 because if T is a non-POD class type
//the default constructor for T is called
Struct *b = new Struct(); //value initializes Struct, which calls the default ctor.
//memberVariable will be initialized to 0 in this case also.
РЕДАКТИРОВАТЬ:
Как @Johannes заметил, что переменная-член примитивного типа (int, bool, float, enum, pointer) value-initialized
не default initialized
,
Для примитивных типов инициализация по умолчанию означает, что объект инициализируется с 0, 0.0 или NULL в зависимости от типа.
Редактировать: Вышесказанное действительно для C++98. В C++03 термины немного переопределены. Теперь, используя инициализатор ()
(что синтаксически возможно только для объектов-членов) приводит к инициализации значения, что для примитивных типов означает, что соответствующее значение 0, 0.0 или NULL сохраняется.
0
Если вы позвоните ()
в примитиве эффект такой же, как при назначении значения по умолчанию, которое было бы дано, если бы оно было статичным.
Инициализация по умолчанию неклассовых переменных с автоматической и динамической продолжительностью хранения создает объекты с неопределенными значениями (статические и локальные для потока объекты инициализируются нулем)
Ссылки и константные скалярные объекты не могут быть инициализированы по умолчанию. см. ниже пример
#include <string>
struct T1 { int mem; };
struct T2
{
int mem;
T2() { } // "mem" is not in the initializer list
};
int n; // static non-class, a two-phase initialization is done:
// 1) zero initialization initializes n to zero
// 2) default initialization does nothing, leaving n being zero
int main()
{
int n; // non-class, the value is indeterminate
std::string s; // class, calls default ctor, the value is "" (empty string)
std::string a[2]; // array, default-initializes the elements, the value is {"", ""}
// int& r; // error: a reference
// const int n; // error: a const non-class
// const T1 t1; // error: const class with implicit default ctor
T1 t1; // class, calls implicit default ctor
const T2 t2; // const class, calls the user-provided default ctor
// t2.mem is default-initialized (to indeterminate value)
}
Это зависит от того, как вы создаете экземпляр класса, если вы используете ClassName(), классы POD по умолчанию инициализируются нулем для вызываемого конструктора класса, отличного от класса POD, но если вы используете ClassName, без скобок инициализация по умолчанию не происходит.
Нативные типы, такие как int, обычно получают garbage value
например что бы ни происходило, он находится в области памяти, в которой он создан. Однако это не определено в стандарте и может также быть инициализировано равным 0, что довольно часто встречается, например, в. отладочные сборки.
РЕДАКТИРОВАТЬ. Но в принципе вы никогда не должны доверять неинициализированной переменной для хранения чего-то конкретного; Всегда определяйте ценности сами.