Психическая модель для void * и void **?
Примечание. Я опытный программист на С++, поэтому мне не нужны никакие основы указателя. Это просто, что я никогда не работал с void**
и с трудом получаю мою ментальную модель, скорректированную на void*
vs. void**
. Я надеюсь, что кто-то сможет объяснить это в хорошем смысле, чтобы легче запомнить семантику.
Рассмотрим следующий код: (компилируется, например, VС++ 2005)
int main() {
int obj = 42;
void* ptr_to_obj = &obj;
void* addr_of_ptr_to_obj = &ptr_to_obj;
void** ptr_to_ptr_to_obj = &ptr_to_obj;
void* another_addr = ptr_to_ptr_to_obj[0];
// another_addr+1; // not allowed : 'void*' unknown size
ptr_to_ptr_to_obj+1; // allowed
}
Ответы
Ответ 1
void*
- это указатель на что-то, но вы не знаете, что. Поскольку вы не знаете, что это такое, вы не знаете, сколько места оно занимает, поэтому вы не можете увеличивать указатель.
void**
является указателем на void*
, поэтому он является указателем на указатель. Мы знаем, как много указателей на комнату занимают, поэтому мы можем увеличивать указатель void**
, указывая на следующий указатель.
Ответ 2
A void*
указывает на объект, тип которого неизвестен компилятору.
A void**
указывает на переменную, которая хранит такой void*
.
Ответ 3
A void *
может указывать на что угодно (кроме функций). Таким образом, он может даже указывать на указатели, поэтому он может даже указывать на другие объекты void *
.
A void **
- это указатель на void *
, поэтому его можно использовать только для объектов void *
.
Ответ 4
void
вводит в заблуждение, потому что это звучит как null
. Однако лучше думать о void
как о неуказанном типе. Таким образом, void*
является указателем на неуказанный тип, а void**
является указателем на указатель для неуказанного типа.
Ответ 5
void
- это тип, который не имеет объектов.
void *
является обычным скалярным типом.
void **
также является обычным скалярным типом, который указывает на void *
.
void *
может использоваться для указания на что угодно, но я предпочитаю использовать его только для неинициализированного хранилища. Обычно существует лучшая альтернатива указанию a void *
на фактическом объекте.