Показаны сообщения с ярлыком syntax. Показать все сообщения
Показаны сообщения с ярлыком syntax. Показать все сообщения

воскресенье, 8 апреля 2012 г.

new без скобок.

Возможно, для вас будет новостью, что в C++ можно писать как «new T()», так и «new T».

Можно сперва подумать, что это какой-то синтаксический сахар, и эти конструкции полностью идентичны. Это не так. Конечно, если явно определен конструктор T::T(), то, non c’è problema, вызовется именно он и разницы не будет никакой.

Если же явного конструктора по умолчанию не определено, то «new T()», в отличие от «new T», заполнит все поля объекта нулями. Если быть совсем точным, то в первом случае будет сделана «инициализация значением» (value-initialization), а во втором — «инициализация по умолчанию» (default-initialization), и то только для non-POD типа. Инициализация значением означает вызов конструкторов по умолчанию, если они явно определены пользователем, а если не определены — обнуление всех членов. Инициализация — это вызов конструкторов по умолчанию, какими бы они не были: сгенерированы компилятором или определены пользователем. При этом сгенерированные компилятором конструкторы ничего сами не обнуляют. Очевидно, инициализация по умолчанию будет быстрее. Подробнее о разных видах инициализации можно почитать в разделе 8.5.5 стандарта C++03 / С++11.

В более старом C++98 нет понятия value-initialization, поэтому «new T()» будет обнулять только POD-типы (если верить этому).

Кстати, та же самая штука со скобками справедлива не только для new, но и для локальных переменных на стеке. Например:

int i1; // i1 == garbage
Но вот так будет не совсем верно:
int i2(); // i2 == 0? wrong!
Переменная i2 трактуется как функция без аргументов, возвращающая int.

суббота, 24 марта 2012 г.

Куда «приклеивается» const?

При объявлении типа в C++ может быть не очевидно, к чему относится модификатор const. Например, что в точности означают такие объявления:

const int * p1;
int const * p2;
int * const p3;

И вообще, к чему относится const в общем случае?
Правило простое: const относится к тому, что стоит непосредственно слева от него; либо справа, если слева ничего нет.

Исходя из этого, p1 и p2 имеют одинаковые типы — указатель на константу.
В объявлении p3 const относится к *, то есть к указателю. Поэтому p3 — указатель-константа на readwrite-переменную.

Еще парочка примеров:
int const * const p4;  // константный указатель на константу
int * const * p5;  // указатель на константный указатель.

Ссылки по теме: