Параметры функции: Копировать или указатель? - PullRequest
9 голосов
/ 04 ноября 2008

Я новичок в C ++ и у меня есть несколько вопросов, это один из них.

Есть ли какая-либо причина, когда вы используете функцию, которая принимает один или несколько параметров, параметры которых, как вы знаете, всегда будут храниться в переменной перед вызовом функции, чтобы передать копию переменной, а не указатель к переменной?

Я говорю о производительности. Мне кажется, что для передачи копии всей структуры потребовалось бы гораздо больше ресурсов, чем просто указатель (4 байта).

Ответы [ 6 ]

12 голосов
/ 04 ноября 2008

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

  1. Объект равен или меньше указателя. Прямой доступ к значению всегда будет быстрее, чем разыменование указателя.
  2. Структура достаточно мала, чтобы компилятор помещал ее в стек. В этом случае доступ к значениям в структуре осуществляется с помощью индексированных режимов адресации, а не косвенных индексированных режимов адресации. Первые, как правило, быстрее.

Существуют и другие причины, по которым вы хотите передать копию, а не ссылку, а именно ваша функция будет вносить изменения в структуру, которые не будут отражены обратно вызывающей стороне. Хотя это, как правило, плохая практика, передача параметра по значению гарантирует, что представление вызывающей стороны не будет изменено неправильно.

Теперь для части ответа, которую вы, вероятно, не хотите слышать: обычно это не имеет большого значения! Используйте метод передачи параметров, наиболее подходящий для семантики вашей программы. Если позже вы обнаружите, что в определенной области есть узкое место в производительности, тогда сконцентрируйтесь на улучшении производительности. Не переусердствуйте!

10 голосов
/ 04 ноября 2008

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

Обычно семантика значения может быть выражена либо передачей значения по значению, либо константной ссылкой

void value_semantics(my_obj obj);
void value_semantics(const my_obj& obj);

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

Чтобы получить семантику ссылок, вы можете выбрать передачу по ссылке или по указателю, так как другие уже сказали, что ссылки более естественны, чем указатели в C ++ (вам не нужно использовать адрес оператора &) и единственное реальное преимущество указателей - если вы хотите включить значения NULL.

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

4 голосов
/ 04 ноября 2008

Избегайте использования указателя. Используйте константу Ссылка, если параметр IN, иначе просто ссылка для параметра IN OUT

4 голосов
/ 04 ноября 2008

Указатель открывается для ошибок, поскольку он позволяет вызываемому объекту изменять объект. Указатели могут быть 0, что приводит к сбоям, и это создает необходимость проверки 0 указателей повсюду, это может раздражать. Использование ссылок C ++, объявленных const, где это возможно, позволяет обойти обе эти проблемы.

2 голосов
/ 04 ноября 2008

Основной вопрос не в производительности, а в семантике и в том, изменяет ли ваша функция данные в структуре.

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

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

Если вас не устраивает концепция передачи указателей на структуры, вам следует немного попрактиковаться, потому что это типичный способ работы со структурами в C и C ++.

Что касается производительности, копирование структуры - это больше работы, но это довольно незначительно в плане вещей. Сначала обратите внимание на семантику кода.

1 голос
/ 04 ноября 2008

ссылка является более распространенной или постоянной ссылкой, если они не собираются изменяться.

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