2016-04-27 9 views
3

Я читаю C++ Primer Book (пятое издание), и у меня есть вопрос по книге, которую я читаю. Он говорит:Разница между Авто и Пустотой?

Тип void* представляет собой специальный тип указателя, который может содержать адрес любого объекта. Как и любой другой указатель, указатель void* имеет адрес, , но тип объекта по этому адресу неизвестен.

Хорошо, поэтому я это понимаю, но ... У меня много противоречий с утверждением. Во-первых, вы не можете использовать auto? Разве он не делает то же самое, что и void? Значение не

void *somePtr; 

и

auto *somePtr; 

то же самое?

Во-вторых, это говорит о том, что тип прикрепленного адреса неизвестен. Вы не можете использовать typeid, чтобы получить тип? Как это:

int a = 5; 
auto *somePtr = 5; 
std::cout << typeid(*somePtr).name() << std::endl; 
+1

'int x; double y; void * p = & x; p = & y; 'не будет работать с' auto * '. –

+0

Почему бы не @TavianBarnes ..? – amanuel2

+4

Потому что 'auto *' будет выведено в 'int *'. –

ответ

10

Вы пытались запустить свои примеры через компилятор?Как это происходит, ни

auto * p; // error 

ни

int a = 0; 
void * p = &a; 
std::cout << typeid(*p) << '\n'; // error 

будет компилировать в то время как

void * p; 

и

int a = 0; 
auto * p = &a; 
std::cout << typeid(*p) << '\n'; 

отлично.

Чтобы дать неформальную и легко запомнить аналогию void * и auto *, думать о void * p, как говорит компилятор

Не заботьтесь о том, что p указатель указывает, я разберусь сам (в время выполнения).

тогда auto * p = (expression) говорит компилятору

Пожалуйста Выяснить для меня (во время компиляции), что (указатель) типа (expression) оценивает в и сделать тип p быть соответствующим образом.

По сути, auto * редко бывает полезным. Вместо этого вы можете просто написать auto, и если инициализирующее выражение является типом указателя, то также будет выведено значение auto.

+0

Вау! Помогите мне понять больше об авто ... так что в принципе вы можете заменить 'auto' на' void' ... Тогда почему в мире C++ 11 Добавьте ключевое слово 'auto'? Также @ c650 говорит, что '* void' является плохой практикой в ​​C++ (как он сказал в комментариях вопроса). Вы согласны? Если да, то почему и что я должен использовать вместо '* void', который служит с той же целью? – amanuel2

+1

'auto' означает: вывести тип из инициализатора. 'void' означает: no type. 'auto' по-прежнему строго типизирован. Разница между 'auto' и' auto * 'является тонкой. 'auto *' означает указатель. 'auto' означает любой тип и может быть указателем. Точно так же 'auto &' означает ссылку. – jbruni

+0

Да, я знаю, что @jbruni. Я заявил в своем вышеприведенном комментарии, я полностью понимаю это. Но было просто интересно, почему C++ 11 решил включить 'auto' ..в основном 'void' лучше, чем' auto', потому что его доцент должен вывести тип инициализатора, он всегда «no-type» ... Единственная причина, по которой я могу видеть, когда программист хочет переменную, которую он объявляя, что он является типом его инициализированным типом, preety, как 'template'! Кроме того, я не вижу никаких других преимуществ использования 'auto', или я ошибаюсь? А также @ c650 указал, что '* void' ** сильно ** обескуражен. Зачем? – amanuel2

1

Чтобы ответить на ваш первый вопрос,

недействительными и автоматически не совпадают. When you declare a variable of auto, it means it takes the data types of the value assigned.

напр:

авто а = 5 // 'а' имеет целочисленный тип

автоматического а = 5,0 // 'а' имеет тип поплавка и т.д.,

Фактический разница может наблюдаться при разыменовании.

Вышеупомянутое утверждение «фактическая разница может наблюдаться при разыменовании» отвечает на ваш второй вопрос.

пустота * не может быть deferenced, в то время как автоматический * может быть deferenced

9

auto использует время компиляции type inference: переменная имеет определенный тип, который является его правильный тип, однако тип выводится из его значения. На протяжении всей жизни переменной auto, компилятор будет гарантировать, что он используется в соответствии с его фактическим выведенным типом

void* действительно может содержать адрес любого объекта, но в отличие от auto, вы должны явно конвертировать void* указатель на другой тип перед его использованием. В отличие от auto это преобразование является явным, и в отличие от auto компилятор не может предупредить о неправильном использовании.

0

В случае автоматической переменной в качестве переменной данных берется тип данных, от которого он получает оценку. Например Auto obj = class_obj. Здесь тип данных class_obj стал типом данных obj. Вам не нужно явно помнить и набирать текст. В случае void * вам нужно знать тип данных и явно вводить текст.

2

С точки зрения компилятора:

  • В C++ 11 auto использует те же правила вывода, как template argument deduction. Он в основном сообщает компилятору: «Вывести тип из инициализатора».
  • void * сообщает компилятору: «Вот указатель, указывающий на объект, тип которого не может быть известен во время компиляции».

Для auto фактического типа выводится во время компиляции, так что компилятор может предупреждать о возможных злоупотреблениях.

Для void * фактического типа выводится в коде программистом используя reinterpret_cast приведение к известному типу указателя, как правило, в момент выполнения этого сегмента кода.


С точки зрения программиста:

  • Эй компилятор Я слишком ленив или слишком неуклюжи, чтобы написать этот тип. Я всего лишь auto и дам вам понять остальное. (И он выглядит меньше, чем тип, который я собирался написать.дляintисключения.)
  • Эй компилятора, не смейте связывайтесь с моей void *. Я выясню тип во время выполнения сам (в коде ...), когда мне это нужно.
    • Полезно для полиморфизма времени выполнения, поскольку один и тот же указатель может использоваться для указания объектов разных типов по мере необходимости в контексте.
    • Также полезно, если вы кодируете базовый класс, и клиенту необходимо сохранить объект Определенный пользователем тип, определенный клиентом.

Так NOauto является НЕ эквивалентно void. void средства ничего. На самом деле вы даже не можете объявить переменную типа void. void * однако особый тип указатель это может пункт на все! И auto * является избыточным, просто используйте простой старый auto вместо этого.

В вашем примере,

int a = 5; 
auto *somePtr = 5; 
std::cout << typeid(*somePtr).name(); << std::endl; 

Вы назначен адрес 5 в somePtr, который является незаконным. Излишне заявлять, что *somePtr также является незаконным в этом контексте. Хотя auto, вероятно, выводится на номер int, который вы хотите распечатать.

Хорошо с современными методами C++ вы редко видите void * s и reinterpret_cast s или любые необработанные указатели, за исключением глубоко внутри любых внутренних реализаций библиотеки.

+2

Аналогичным образом вы не можете выполнить 'void &'. – jbruni

+0

Хорошо. Благодаря! –

 Смежные вопросы

  • Нет связанных вопросов^_^