Указатель на аннулирование в C ++? - PullRequest
11 голосов
/ 04 января 2009

Я читаю некоторый код в реализации Ogre3D и не могу понять, что означает переменная типа void *. Что означает указатель на void в C ++?

Ответы [ 6 ]

39 голосов
/ 04 января 2009

Указатель на void, void* может указывать на любой объект:

int a = 5;
void *p = &a;

double b = 3.14;
p = &b;

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

4 голосов
/ 04 января 2009

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

3 голосов
/ 04 января 2009

Это необработанный указатель на место в памяти. Он не позволяет использовать арифметику указателей, например, char * или int *.

Вот несколько примеров использования

http://theory.uwinnipeg.ca/programming/node87.html

2 голосов
/ 04 января 2009

Это указатель на что угодно - просто кусок памяти, с которым вы можете играть - может быть объектом, может быть символом. Вы должны сыграть что-нибудь полезное с ним.

1 голос
/ 05 января 2009

Пустой указатель не может указывать на члена класса в C ++.

1 голос
/ 05 января 2009

Построение из моей предыдущей публикации ...


ВНИМАНИЕ: Все адреса памяти здесь вымышленные. Я просто делаю их, чтобы проиллюстрировать точку.


Дано:

int data[] = {10,11,12};

Теперь у нас есть:

0xffff0000-0xffff0003  with a value of (int)(10)
0xffff0004-0xffff0007  with a value of (int)(11)
0xffff0008-0xffff000b  with a value of (int)(12)

не собираюсь перейти к порядку байтов с прямым порядком байтов и байтов с прямым порядком байтов здесь.)

Если у нас есть:

int * p = data;

Теперь у нас есть другая область памяти где-то еще, скажем:

 0xaaaa0000-0xaaaa0003  with a value of (int*)0xffff0000

Мы можем использовать p [1] [или * (p + 1)] для ссылки * (int *) (0xffff0004) [= 11] на sizeof (int) = 4 и 0xffff0000 + sizeof (int) = 0xffff0004.

Если у нас есть:

void * v = data;

Теперь у нас есть другая область памяти где-то еще, скажем:

 0xbbbb0000-0xbbbb0003  with a value of (void*)0xffff0000.

Однако void не имеет никакой связанной информации о sizeof (). Мы не можем увеличивать или уменьшать указатель. Мы не можем разыменовать доступ к данным, хранящимся в 0xffff0000. Мы можем использовать это значение только как необработанный адрес памяти.

Если мы хотим использовать данные, хранящиеся в (void *) 0xffff0000, нам сначала нужно привести их к соответствующему типу.

Тем не менее, (void *) все еще весьма полезен в качестве средства передачи адресов в произвольные структуры данных вокруг. Например, memset (). Не имеет значения, обнуляю ли я struct tm или struct sockaddr . Нам просто нужен указатель на структуру и ее размер.

(Это должно быть само собой разумеющимся, но ... Остерегайтесь использования memset для обнуления экземпляра класса и, при этом, перезаписи таблицы виртуальных указателей.)

...