2010-11-20 2 views
3

Я смотрю через API, написанной в C++, и я запутался, что означает следующий тип параметра:Что означает тип параметра void * & mean и каково его использование?

void*& data

Означает ли это, пользователь должен передать ссылку на указатель недействительным? Если это правда, в чем смысл? Я имею в виду, что void * уже косвенен, так почему бы вам когда-нибудь захотеть перенаправить его снова?

ответ

2

Трудно сказать, не видя его использования, но вы указываете, что ссылка является уровнем косвенности. Было бы странно, если бы это был указатель на указатель? Они довольно распространены - на самом деле вы имеете дело с ними, когда принимаете аргументы командной строки и получаете указатели на указатели на символы. Другим примером может быть, если вы делаете хэш-карту с использованием ведер и хотите вернуть указатель на указатель, который запустил ведро.

Суть в том, что иногда вам нужно несколько уровней косвенности. Это правда, что указатели смешивания и ссылки могут быть изворотливыми, но для этого есть веские причины. Одной из распространенных причин является необходимость взаимодействия кода C++ с C apis. Многим системным вызовам POSIX требуются указатели void, которые передаются, а затем меняются, поэтому рассматриваемая функция C++ может выступать в качестве обертки вокруг этого.

+0

Я понимаю, что вы говорите. Я видел 'void **' раньше, но никогда не 'void * &'. Я думаю, когда вы думаете, что все это имеет смысл. – wwahammy

6

void * означает pass-by-pointer в C++, то есть вы передаете указатель, но на самом деле это копия указателя. Если вы изменили этот указатель в своей функции, например, изменили его адрес, это не отразилось на указателе, который вы передали.

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

+0

Я думаю, что передачи по указателю в этом случае является своего рода некорректным; void * - это только тип данных, который хранит адрес. void * & является просто синтаксическим сахаром C++ для void **, другим типом данных, который хранит адрес. Если вы перейдете на адрес, хранящийся в пустоте **, вы найдете пустоту *. – eplawless

+3

@eplawless: Ссылки не являются синтаксическим сахаром для указателей. Они обычно реализуются с помощью указателей, вот и все. Рассмотрим, например, что ссылки не могут быть пересмотрены, что они (на языке) являются только псевдонимами вместо отдельных переменных и что они могут использоваться для продления срока службы временного. –

+0

@Georg: Только ссылки на C++ 0x rvalue могут быть связаны с временной функцией внутри функции. Если вы имеете в виду через передачу параметров, они по-прежнему являются синтаксическим сахаром для указателей: ваш объект создается в стеке, а указатель на объект в стеке передается в вашу функцию. Вы правы, что они закодировали дополнительные ограничения в ссылках, но в конце концов они представляют собой не что иное, как ограниченные указатели, и их возможности по-прежнему являются подмножеством указателей ». Мне гораздо удобнее думать о них в этих терминах при разработке на C++. – eplawless

1

Но будьте осторожны, чтобы не возвращать ссылку на местную пустоту *. Не делать что-то вроде этого:

void*& f() 
{ 
int* a=new int(10); 
void* x=(void*)a; 
return x; 
} 
+0

почему бы не сделать это, я тестирую его, он работает нормально, вы имеете в виду, что он такой же, как 'void * f()'? – toolchainX

+0

Это UB (неопределенное поведение), поэтому он может работать иногда. Но не всегда. В вашем случае, возможно, вы вызвали 'f()', а затем попытались использовать значение, которое оно вернуло сразу после вызова функции, и стек, созданный для локальных переменных внутри 'f()', к этому времени не был перезаписан, но если вы пытались вызвать 'f()', затем выполните некоторую работу (объявите некоторые новые переменные, функции вызова), которые вы потерпите неудачу. –

+0

спасибо! Я понял. – toolchainX