Возвращение указателей или ссылок из функций C ++

Когда вы хотите вернуть экземпляр из метода, вы создаете объект и отправляете указатель назад или ссылку назад? Каков правильный метод и сигнатура метода для этого?

8
задан deft_code 20 August 2010 в 20:30
поделиться

6 ответов

Это действительно зависит от области действия вашего экземпляра, который контролирует время жизни экземпляра. Если это локальный экземпляр, вы можете выполнить возврат по значению, но вам придется дважды возместить затраты на создание и разрушение объекта (если вы не используете RVO ). Другой вариант - вернуть указатель, построив объект в куче внутри вашей функции. Однако при таком подходе клиент будет нести ответственность за удаление выделенной памяти и всегда подвержен утечкам памяти. Вот почему вам понадобится какой-то умный указатель. Код Андерса Абеля наглядно иллюстрирует два вышеуказанных подхода на примерах кода. Кстати, вы не можете вернуть ссылку на локальный экземпляр, поскольку экземпляр выйдет из области видимости после завершения функции.

0
ответ дан 5 December 2019 в 06:08
поделиться

Если вы имеете в виду нечто вроде Заводского метода , обычно вы возвращаете указатель. Еще лучше, верните умный указатель, и вы не создадите больше утечек в силу использования необработанного указателя.

Пример:

std::auto_ptr<Gizmo>  MyFactory::CreateGizmo()
{
  return new Gizmo;
}
2
ответ дан 5 December 2019 в 06:08
поделиться

В C ++ есть много способов сделать это. К сожалению, большинство из них приводит к путанице в отношении того, кто отвечает за выделение и освобождение объекта. Я рекомендую два метода:

// Return a real object, automatic stack allocation.
Foo GetFoo1()
{
   Foo f;
   // Init f.
   return f;
}

// Use a smart, reference counted pointer that handles deallocation itself.
boost::shared_ptr<Foo> GetFoo2()
{
   boost::shared_ptr<Foo> f(new Foo);
   // Init f
   return f;
}
8
ответ дан 5 December 2019 в 06:08
поделиться

Ответ зависит от того, что именно вы делаете и кто отвечает за освобождение.

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

SomeObject* constructObject ()
{
   SomeObject* obj = new SomeObject ();
   return obj;
}

Затем в другой функции

void functionThatNeedsObject ()
{
   SomeObject* obj = constructObject ();
   //You must delete obj when done
}

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

Не делайте этого:

int& DoubleValue(int nX)
{
   int nValue = nX * 2;
   return nValue; // return a reference to nValue here
} // nValue goes out of scope here

Вы можете возвращать ссылки на переменные-члены или переменные, переданные в качестве аргументов функции.

SomeStruct& RefFunction(SomeStruct& nX, SomeStruct& nY)
{
    return nX;
} //nX is still in scope because it was passed to us
7
ответ дан 5 December 2019 в 06:08
поделиться

Если я создаю экземпляр исключительно для возврата, я бы возвращался по значению в качестве первого предпочтения.

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

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

4
ответ дан 5 December 2019 в 06:08
поделиться

Либо возвращайте по значению (люди ошибочно полагают, что это медленно), либо, если вы возвращаете переопределение полиморфного типа, возвращайте auto_ptr (или лучше unique_ptr в C++0x).

Причина, по которой вы НЕ используете shared_ptr, заключается в том, что вы никогда не сможете вытащить из него свой указатель и использовать другую семантику владения.

Никогда не возвращайте ссылку на локальный экземпляр.

6
ответ дан 5 December 2019 в 06:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: