Нужно ли использовать ссылочные параметры для возврата значений? - PullRequest
1 голос
/ 07 апреля 2009

Если HANDLE является выходным параметром, необходимо ли использовать ссылку на HANDLE или использовать РУЧКУ напрямую?

bool fn(HANDLE h_result);

или

bool fn(HANDLE& h_result);

Ответы [ 4 ]

11 голосов
/ 07 апреля 2009

Для возврата значений вы можете:

  1. Использовать ссылку в качестве параметра
  2. Использовать указатель в качестве параметра
  3. На самом деле вернуть значение через return

При указании следующего:

bool fn(HANDLE h_result);

Вы делаете копию h_result. Поэтому, если вы измените его в своей функции, вы измените копию, а не оригинал.

При работе с указателями концепция точно такая же. Просто помните, что указатель - это просто переменная, которая содержит адрес памяти. Неважно, что находится в этом адресе памяти. Если вы хотите вернуть адрес памяти через параметр, вам нужно использовать указатель на указатель или ссылку на указатель.

1 голос
/ 07 апреля 2009

РУЧКА - это в основном пустота *, вот и все. Измените указанный код на

bool fn(void* pResult);

и ответ будет понятнее. Если вы хотите, чтобы значение, назначенное для pResult, было доступно любому, кто вызвал fn, вам придется изменить функцию на

bool fn(void*& pResult);

, что эквивалентно

bool fn(HANDLE& h_result);
1 голос
/ 07 апреля 2009

В вашем случае я бы предпочел сделать что-то вроде:

HANDLE fn()

и вернуть недействительный (или NULL) дескриптор в случае сбоя и действительный дескриптор в противном случае. Конечно, я предполагаю, что тип HANDLE в некоторой степени похож на то, что Win32 API использует в качестве дескриптора.

Что касается вашего вопроса, передайте выходные параметры по ссылке или по указателю, так что либо:

bool fn( HANDLE& out)

или

bool fn( HANDLE* out)

Во втором примере вы должны убедиться, что переданный указатель не равен NULL, обычно с assert:

bool fn( HANDLE* out)
{
   assert( NULL != out);
   // ... rest of the code
}

Другим недостатком передачи выходных параметров в качестве указателей является то, что вы не можете точно знать, действителен ли переданный указатель (был инициализирован или нет).

Передача по ссылке иногда менее читаема, когда дело доходит до выходных параметров. Вызов

bool result = fn (myHandle);

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

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

0 голосов
/ 07 апреля 2009

Если вы используете «HANDLE» напрямую, ни одно из изменений, внесенных вами в вызов функции, не будет передано объекту вызывающей стороны.

например. Для "bool fn (HANDLE h_result);"

HANDLE oH = CreateHandle(); // Some function
oH.SetName("Sam");
bool bRet = fn(oH);   // Assume we call oH.SetName("Max");
cout << oH.GetName() << endl;  //will print "Sam"

Но если вы используете "bool fn (HANDLE & h_result)"; вывод будет "Макс"

Таким образом, выбор будет зависеть от приложения. Если вам нужно сохранить изменения состояния, сделанные в «fn», передайте параметр в качестве ссылки. Если нет, передайте копию с помощью «bool fn (HANDLE h_result);»

P.S. "Bool fn (HANDLE h_result)" будет довольно трудоемким при обработке, так как существует много вызовов конструктора копирования

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