Разница между указателем на указатель и ссылкой на указатель (C ++) - PullRequest
6 голосов
/ 08 декабря 2011

У меня есть немного кода COM, который использует указатели интерфейса.Первоначальный автор кода реализовал функции, которые возвращают указатель интерфейса следующим образом:

HRESULT Query ( IN BSTR sQuery, OUT IEnumWbemClassObject* &pEnumerator ); // (1)

вместо традиционного

HRESULT Query ( IN BSTR sQuery, OUT IEnumWbemClassObject** ppEnumerator ); // (2)

Функция (1) вызывается так:

hRes = Query ( sQuery, pEnumerator ); // (3)

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

Есть ли преимущество в использованииto-pointer вместо указателя на указатель для параметров out?

Ответы [ 4 ]

4 голосов
/ 08 декабря 2011

Первый пример - это ссылка на указатель , т.е.ссылка на тип IEnumWbemClassObject*:

HRESULT Query ( IN BSTR sQuery, OUT IEnumWbemClassObject* &pEnumerator );

Поэтому, если pEnumerator объявлено как IEnumWbemClassObject* (что я предполагаю, что это так), вам не нужно явно передавать адресpEnumerator функции или разыменования переменной внутри функции, чтобы изменить, где pEnumerator указывает (что в противном случае потребовалось бы с аргументом IEnumWbemClassObject**).

Ссылка на указатель имеетТо же поведение, что и в случае ссылки на любой другой тип, просто представьте в приведенном выше примере «ссылку на указатель» и , а не a «указатель на ссылку." Нет такой вещи, как указатель на ссылку.

4 голосов
/ 08 декабря 2011

Преимущества те же, что и при использовании ссылок вместо указателей:

  • простота
  • ссылки не могут быть нулевыми, поэтому присвоение ссылки в Query не приведет к нарушению доступа

Обратите внимание, что исходное описание было ошибочным: IEnumWbemClassObject* & является ссылкой на указатель, а не указателем на ссылку.

2 голосов
/ 08 декабря 2011

Лучше думать о Типе & foo * как о ссылке на указатель, а не об обратном, так как это больше не означает, что вы можете изменить ссылку через указатель и другие подобные C ++ -ломать идеиЭто также делает вызов этой функции немного легче верить, так как это все равно, что передавать что-либо еще по ссылке, без разыменования или специальных символов.

1 голос
/ 08 декабря 2011

Это потому, что указатель и ссылка представляются одинаково в обычной реализации C ++ (однако, это подробности реализации, а не часть стандарта. Также его ссылка на указатель, а не указатель на ссылку, вам вообще не разрешено создавать указатель на ссылку.

...