Есть ли смысл передавать указатель по ссылке в функцию?

97
06 февраля 2021, 21:30

К примеру есть следующий код:

#include <cassert>
class MyClass {
  int m_Data;
public:
  MyClass(int initVal) : m_Data(initVal) {}
  void SetData(int data) { m_Data = data; }
  int GetData() { return m_Data; }
};
// Передача по указателю:
void MyFunctionPtr(MyClass* arg) {
  arg->SetData(arg->GetData() * arg->GetData());
}
// Передача указателя по ссылке:
void MyFunctionPtrRef(MyClass*& arg) {
  arg->SetData(arg->GetData() * arg->GetData());
}
// Передача по ссылке:
void MyFunctionRef(MyClass& arg) {
  arg.SetData(arg.GetData() * arg.GetData());
}
int main(int argc, char* argv[]) {
  MyClass* my = new MyClass(2);
  MyFunctionPtr(my);
  assert(my->GetData() == 4);
  MyFunctionPtrRef(my);
  assert(my->GetData() == 16);
  MyFunctionRef(*my);
  assert(my->GetData() == 256);
  delete my;
  return 0;
}

Является ли передача указателя по ссылке MyClass*& arg менее затратной, чем передача указателя по значению MyClass* arg? За счет того, что при передаче по ссылке не происходит копирования указателя. Какой из трех способов наиболее быстрый:

  • передача указателя по значению;
  • передача указателя по ссылке;
  • передача по ссылке.

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

Answer 1

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

(*) Конечно, это всё не по стандарту и прочее и прочее, но для примерного понимания разницы этого должно быть достаточно.

Answer 2

Имеет смысл, если использовать указатель вместо итератора в функции, например

void add(int*& it, int add){
    *it += add;it++;
}
int main(){
  int a[2] = {1,2};
  int* b = a;
  add(b, *b);
  add(b, *b);
  cout<<a[0]<<','<<a[1]; //2,4
}
READ ALSO
Шаблоны классов [дубликат]

Шаблоны классов [дубликат]

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

93
Сортировка слов по алфавиту

Сортировка слов по алфавиту

Задача такова, что в обычном тексте на русском языке, который находится в файлеtxt выделить оттуда кусок текста, выбрать из него слова и отсортировать...

113
C, откуда 3 байта?

C, откуда 3 байта?

Вот простенький код, на экран выводит число равное 3, почему? откуда взялись эти 3 байта

92
Изменение размера окна с помощью мышки

Изменение размера окна с помощью мышки

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

142