В Передача изменяемого параметра функции c ++ я ответил, когда использовать ссылку вместо указателя.
И наоборот, предпочитайте указатель на ссылку, если выполняется одно из следующих условий:
Некоторые люди также предпочитают указатель, когда объект, на который указывает указатель, должен быть видоизменен, говоря, что разница между ссылкой на константу и ссылкой на неконстантную форму для читателя недостаточно очевидна.
Помимо стандартного использования параметра-указателя (о котором уже говорили другие), одна из причин, о которой я могу думать, - это реализация обратных вызовов. Вы можете иметь функцию, которая принимает указатель функции в качестве параметра.
Две причины:
Указатель на 32-битной платформе имеет размер всего 4 байта. Если данные, которые вы передаете в функцию, больше 4 байт, вы сэкономите время вызова, передав структуру по ссылке, а не по значению. (Позже вы можете потерять это преимущество в производительности на издержках перенаправления, но именно здесь на помощь приходит профилирование.)
Вы можете передать неконстантный указатель, чтобы позволить функции модифицировать переданные данные.
Указатели - единственный способ принимать строки и массивы в стиле C. Кроме того, они являются единственным способом обмена данными между несколькими потоками (помимо глобальных объектов, которые ... ну).
Есть много причин использовать указатели в качестве параметров. Основная причина - полиморфизм. Указатель может указывать на объект базового класса или подкласс и соответственно вызывать методы этого объекта.
Я рекомендую Accelerated C ++ Кёнига, он хорошо объясняет, как полиморфизм работает в C ++ с помощью указателей (и ссылок).
Если вы передаете простую переменную в функцию, функция создает копию этой переменной для использования в ее области видимости. Когда функция завершает выполнение, любые изменения, внесенные в переданную простую переменную, отображаться не будут. Это связано с тем, что сама переменная никогда не изменялась внутри функции, а изменялась только ее копия. Передача указателя на переменную функции решает эту проблему.
int some_function(int num) {
return num++;
}
int num1 = 15;
std::cout << some_function(num1) << std::endl; //prints 16
std::cout << num1 << std::endl; //prints 15
Есть много причин, но ссылки должны быть "стандартом". Используйте указатели, только если ссылка не подходит. Некоторые плюсы и минусы:
Указатели могут использоваться для передачи огромных массивов без огромного объема памяти
В случае родовых типов, оптимизация компилятора может работать лучше со ссылками, потому что компилятор имеет больше информации об используемых типах
Ссылки, возможно, делают код более читабельным, более согласованным с java и c# и, следовательно, более читаемым для другими типами разработчиков
Ссылки на самом деле передают не весь объект, а скорее указатель. весь объект, а скорее указатель на него, однако больше информации о типе доступна компилятору.
Я полагаю, вы имеете в виду указатели в отличие от ссылок? С указателями можно сделать следующее: установить их в NULL, что позволяет задать неинициализированное состояние. Иногда это может быть полезно, но следствием этого является то, что если вы хотите добиться того, чтобы NULL не мог быть передан в вашу функцию, то использование ссылки делает это очевидным.
Есть еще одно различие между указателем и ссылками: -pointer может быть NULL-указателем -reference всегда ссылается на реальный объект [f (T & v); f (NULL); не очень хорошая идея]
IMO, указатели во многих документах по C++ представляются гораздо более важными, чем они есть на самом деле, в то время как ссылки редко обсуждаются в вводном материале (кроме кратких упоминаний в терминах параметров).
Хотя указатели, безусловно, имеют ценность (массивы, строки, динамическая память и т.д.), многие из их функций могут быть реализованы более просто с помощью ссылок. Единственный раз, когда я действительно регулярно использую параметры указателей, это когда я использую стороннюю библиотеку, в которую встроено такое использование.
Использование ссылок устраняет шаг копирования-присвоения, неявный в прямых параметрах класса, и не требует утомительного разыменования указателей (использование * или ->) снова и снова. Кроме того, обучение использованию ссылок важно для таких приложений, как перегрузка операторов, что жизненно важно для точного контроля вашего кода.