Подтвердить что ты не робот

Что такое указатели void для С++?

Мой вопрос прост: Что такое указатели void для С++? (Те вещи, которые вы объявляете с помощью void* myptr;)

Каково их использование? Могу ли я заставить их указывать на переменную любого типа?

4b9b3361

Ответ 1

В принципе, остаток от C.

Каково их использование?

В C они были и используются широко, но на С++ я думаю, что они очень редко, если вообще когда-либо нужны, поскольку у нас есть полиморфизм, шаблоны и т.д., которые обеспечивают гораздо более чистый и безопасный способ решения тех же проблем, в C можно использовать указатели void.

Могу ли я заставить их указывать на переменную любого типа?

Да. Однако, как указывали другие, вы не можете напрямую использовать указатель void - вы должны сначала перенести его в указатель на конкретный тип данных.

Ответ 2

Да, это C-конструктор (не С++-специфический), который позволяет вам объявлять переменную-указатель, указывающую на любой тип. Вы не можете делать что-либо с таким указателем, за исключением того, что возвращаете его к реальному объекту, на который он указывает. В современном С++ void * в значительной степени ушел из моды, что во многих случаях приводит к созданию общего кода на основе шаблонов.

Ответ 3

Об одном из немногих применений, которые существуют для указателей void в С++, является их использование при перегрузке операторов new. Все операторы new возвращают тип void* по определению. Кроме того, то, что говорили другие, верно.

Ответ 4

От cplusplus.com:

Тип указателя типа void является специальным тип указателя. В С++, void представляет собой отсутствие типа, поэтому void указатели - это указатели, которые указывают к значению, которое не имеет типа (и, следовательно, также неопределенной длины и неопределенные свойства разыменования).

Это позволяет указателям void указывать на любой тип данных, от целочисленного значения или float для строки символов. Но взамен у них отличный ограничение: данные, указанные ими не могут быть разыменованы логично, поскольку у нас нет типа разыгрывать), и по этой причине мы всегда будем адрес в указателе void для некоторых другой тип указателя, указывающий на конкретный тип данных до разыгрывая его.

Ответ 5

Скрыть тип. Он все еще имеет свои действительные применения в современном С++. Копайте исходный код в boost, и вы найдете несколько. Как правило, использование пустоты * очень глубоко утопает в недрах более сложной конструкции, которая обеспечивает безопасность типа интерфейса при выполнении черной и злой магии внутри.

Ответ 6

Они когда-то в C выполняли задание быть указателем-на-ничего, указателем, который вы передавали в библиотеки, и они возвращали вам данные userdata. Пустота * вообще бесполезна, если программист не знает своего контекста каким-то образом, так как вы не знаете, что с другой стороны, вы ничего не можете сделать с данными. За исключением передачи указателя на другой код, который знает.

Я не понимаю, почему люди не просто использовали типы undefined, т.е. непрозрачные указатели. Введите безопасность, данные пользователя.

В современном С++ указатель на void почти полностью заменяется полиморфизмом и генерируемым шаблоном общим кодом. Тем не менее, вам все равно придется использовать их для взаимодействия с собственным C-кодом. Чтобы безопасно использовать void * в любом конкретном контексте, только когда-либо передавайте один тип в void *. Таким образом, вы точно знаете, на что это указывает. Если вам нужно больше типов, вы можете быстро и быстро struct safevoidptr { base* ptr };
или
struct safevoidptr { void* ptr; int type; };
Я считаю, что dynamic_cast также может преобразовывать void * в полиморфные типы, хотя я никогда не использовал dynamic_cast, поэтому не задумывайтесь об этом.

Ответ 7

Указатель void может указывать на что угодно, если его память: -)

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

Ответ 8

Указатель на void является самым близким к указателю языка ассемблера. Это общий указатель, который резервирует место для адреса или местоположения чего-либо (функции или точки привязки). Как утверждали другие, он должен быть брошен, прежде чем он может быть разыменован.

Указатель void - это популярный инструмент для представления концепций Object Orient на языке C. Одна проблема с указателем void заключается в том, что контент может не соответствовать восприятию приемника. Если вызывающий абонент устанавливает указатель на квадрат, но приемная функция ожидает указателя на кошку, undefined и странные вещи произойдут с нажатием указателя.

Ответ 9

Поскольку уже есть много хороших ответов, я бы просто предложил один из наиболее распространенных из них: специализация шаблонов. Если я не ошибаюсь, в книге Страуструпа есть пример этого: специализирующий вектор как вектор, а затем имеющий вектор для вывода (в частном порядке) из вектора. Таким образом, вектор будет содержать только простые легкосшитые коды (т.е. Вызов соответствующих функций из вектора). Это уменьшит количество дублирования, когда вектор будет скомпилирован в программе, которая использует его со многими различными типами указателей.

Ответ 10

void ptr - пустая коробка. Заполните его тем, что хотите, но убедитесь, что вы нанесете отметку (tupecasting)

Ответ 11

Я использую их в своих динамических списках для хранения большего количества объектов (все - указатели).
typedef void* Object; Затем, когда вы объявляете переменную Object, вы можете сохранить в ней любой указатель. Это более или менее полезно в зависимости от потребностей.
Я считаю это очень полезным, когда вам нужно где-то хранить какой-либо указатель, и вы не можете просто вывести все ваши классы из одного. Кроме того, как другие говорили, что лучше использовать шаблоны, полиморфизм и т.д.

Ответ 12

Вещи, которые вы могли бы сделать в C с void, но не можете в С++:

void * автоматически преобразуются в другие типы указателей. (Вы знаете его пустоту * - вы не получаете безопасности типа от принудительного явного приведения)

Struct* p = malloc( sizeof(Struct) );
// vs C++
Struct* p = (Struct*)malloc( sizeof(Struct) );
// Some will argue that that cast style is deprecated too, and c++ programmers 
// need to actually do this:
Struct* p = reinterpret_cast<Struct*>malloc( sizeof(Struct) );
// See what C++ did there? By making you write Struct a 3rd time, you can now be sure
// you know what you are doing!

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

void funcInitializingOutPtr( void** ppOut)
{
  *ppOut = malloc( x );
}

int* out = NULL;
funcInitializingPtr(out);  // C would signal this as an error
funcInitializingPtr(&out); // correct
// vs C++ 
funcInitializingPtr( (void**)&out ); // so much safer needing that exlicit cast.
funcInitializingPtr( (void**)out);   // oops. thanks C++ for hiding the common error

Ответ 13

I belive void * - это ячейка памяти, в которой вы можете придать тип/сохранить что-либо. Я немного Язык Pundit не согласится на это со мной. но я использовал его успешно во многих своих проектах.

Только проблема, которую я вижу, относится к типам безопасности