Передача параметров в функцию по указателю, ссылке и значению

      Комментарии к записи Передача параметров в функцию по указателю, ссылке и значению отключены

Главная Форумы Программирование Программирование на С++ Учебные материалы по С++ Передача параметров в функцию по указателю, ссылке и значению

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 10 мес. назад.

  • Автор
    Сообщения
  • #2726

    questioner
    Участник

    Говорят, что передача по указателю и ссылке эффективнее, чем передача по значению, а передача по ссылке — безопаснее, чем по указателю. Тогда почему вообще используются какие-либо виды передачи, кроме как по ссылке?

  • #2728

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

    int foo(Bar *bar) {
      if (bar != nullptr) { // тут может быть ошибка, если
        return bar->foo(); // указатель не был инициализирован
      }
      return 0;
    }

    Чаще всего указатели используют если необходимо ссылаться на разные объекты одного типа. Это используется во многих шаблонах проектирования, например паттерн State (Состояние) делегирует часть своей работы другому объекту, который в процессе функционирования может изменяться (при изменении состояния):

    state_pattern

    void DiagramItem::setText(string text) {
      state->setText(this, text);
    }
    
    void DiagramItem::move(Position pos) {
      state->move(this, pos);
    }
    
    void DiagramItem::select() {
      if (state)
        delete state;
      state = DiagramEditingItemSelectedState();
    }

Для ответа в этой теме необходимо авторизоваться.