Для чего используется (void*) литье?

Я пытался найти это в Stack Overflow, но я думаю, что из-за синтаксиса и незнания точно, что искать, я немного растерялся.

Я видел, как (void*) использовался для приведения типов, обычно для вызовов функций. Для чего это используется?


person user997112    schedule 31.05.2013    source источник
comment
Не так много, как C. У нас есть лучшие способы сделать большую часть того, для чего он использовался.   -  person chris    schedule 01.06.2013
comment
@chris, не могли бы вы уточнить в ответе ниже и привести пример того, для чего он используется и почему нам больше не нужно делать это на С++?   -  person user997112    schedule 01.06.2013
comment
Мы используем его для взаимодействия с кодом C.   -  person Mooing Duck    schedule 01.06.2013
comment
Вы имеете в виду (void*)?   -  person Pubby    schedule 01.06.2013
comment
@user997112 user997112, честно говоря, я не в лучшем состоянии пассивной памяти, чтобы сегодня придумывать списки примеров, но boost::variant и boost::any - хорошие альтернативы в соответствующих областях.   -  person chris    schedule 01.06.2013


Ответы (4)


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

Пустые указатели более полезны в C, чем в C++. Обычно вам следует избегать использования указателей void и вместо этого использовать перегрузку функций или шаблоны. Проверка типов — это хорошо!

person LukaCiko    schedule 31.05.2013
comment
Скажи мне, если я ошибаюсь; Указатель void в C по сути то же самое (в концепции), что и Object в Java. - person CodyBugstein; 26.11.2013
comment
возможно, было бы правильнее сказать, что указатель void в C - это то же самое (в концепции), что и Object REFERENCE в Java. - person rents; 09.08.2016

Пустой указатель — это указатель на значение, тип и размер которого неизвестны. Я приведу пример того, как его можно использовать в C, хотя другие комментаторы правы, говоря, что его вообще не следует использовать (и, по сути, не нужно) в C++.

Предположим, у вас есть структура, в которой хранятся ключ и значение. Это может быть определено так:

typedef struct item_t
{
    char *key;
    int value;
} item_t;

Таким образом, вы можете использовать эту структуру для сопоставления любого строкового ключа с целочисленным значением. Но что, если вы хотите сохранить произвольное значение? Может быть, вы хотите, чтобы некоторые ключи совпадали с целыми числами, а некоторые — с двойными? Вам нужно определить свою структуру таким образом, чтобы она отслеживала (с помощью указателя) значение произвольного типа и размера. В этом случае void * отвечает всем требованиям:

typedef struct item_t
{
    char *key;
    void *value;
} item_t;

Теперь, если ваше значение — int, вы можете получить его значение, используя (int *) value, а если его значение — двойное, вы можете сделать это, используя (double *) value. Это предполагает, конечно, что код, использующий структуру, знает, какой тип он ожидает увидеть в каком контексте.

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

person CmdrMoozy    schedule 31.05.2013

Это наиболее общий способ предоставления указателя на объект в C/C++. Как object в C# или Java.

person Wolfgang Ziegler    schedule 31.05.2013

Это в основном используется, когда вы хотите передать параметр, который может иметь разные состояния.

Например, в вашем общем коде вы должны передать void* в качестве параметра, а затем в «конкретной» реализации этого кода вы должны привести void* к тому, что хотите.

Общий код, abc.h

void Test(void* pHandle);

Код Windows, abc.cpp

void Test(void* phandle)
{
   WindowsStructure* myStruct = (WindowsStructure*)(pHandle);
    myStruct->getWhatINeed;
}

Код Linux, abc.cpp

void Test(void* phandle)
{
   LinuxStructure* myStruct = (LinuxStructure*)(pHandle);
    myStruct->getWhatINeed;
}
person Oliver Ciappara    schedule 31.05.2013