Страницы

Поиск по вопросам

среда, 27 ноября 2019 г.

Выделение памяти типа auto


Почему данная строка не вызывает у разработчиков стандарта казуса?

auto p = new auto(42);

    


Ответы

Ответ 1



Есть четыре вида длительности хранения памяти под объект (storage duration), и соответственно четыре способа создать объект: статическая, static T variable(expression), потока, thread_local T variable(expression), автоматическая, T variable(expression), динамическая, new T(expression). Было бы странно, если бы вывод типов работал бы только для первых трех способов но не работал бы для динамически выделяемой памяти.

Ответ 2



Когда используется спецификатор типа auto, то реальный тип выводится на основе типа инициализатора. В этом выражении new auto(42) тип создаваемого динамически объекта определяется, исходя из типа выражения, используемого в качестве инициализатора объекта. В данном случае это целочисленный литерал 42 , имеющий тип int. Поэтому создается объект этого типа в динамической памяти и инициализируется значением 42. Сам оператор возвращает указатель на созданный объект, то есть в приложении к данному примеру возвращается указатель int * Поэтому в исходном предложении auto p = new auto(42); тип переменной p в свою очередь определяется из типа инициализатора в правой части от знака =, который, как я указал выше, имеет тип int *. То есть в этом предложении создается два объекта, один - это безымянный объект динамической памяти, а второй - это указатель, возможно, в автоматической или статической области памяти, и тип каждого из этих объектов определяется на основе соответствующего типа выражения, используемого в качестве инициализатора. Вообще-то не следует злоупотреблять спецификатором auto, так как порой это може вызывать затруднения у читающего код, чтобы определить, какой реальный тип компилятор выведет для переменной со спецификатором auto. Рассмотрите следующий, казалось бы, очень простой пример, unsigned int x = 0; long y = 0; auto p = new auto( x + y ); Не каждый сможет правильно ответить, какой будет тип у указателя p, так как помимо всего прочего, правильный ответ зависит в том числе от используемой платформы. Вот вам еще в копилку подобная на первый взгляд странная конструкция на этот ра касающаяся оператора преобразования, о которой можете почитать здесь Сейчас в стандарте C++ появилось много конструкций, которые интуитивно непонятны. Я приведу пример одной из таких конструкций int a[] = { 1, 2, 3 }; decltype( auto ) c = ( a ); Обратите внимание на объявление переменной c и заключение в круглые скобки выражения ( a ). Оказывается, это не совсем одно и то же, что объявление int a[] = { 1, 2, 3 }; decltype( auto ) c = a; где выражение a не заключено в круглые скобки. Это предложение не будет компилироваться в то время как предыдущее предложение с инициализатором в круглых скобках успешно скомпилируется.:)

Ответ 3



Это тоже самое, что int* i = new int(42);

Комментариев нет:

Отправить комментарий