Урок №127. Анонимные объекты

  Юрий  | 

    | 

  Обновл. 16 Июн 2019  | 

 7913

 ǀ   6 

В некоторых случаях переменная может быть нам нужна только временно. Например:

В функции add() переменная result используется как временная переменная. Она не выполняет особой роли, функция использует её только для возврата значения.

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

Вот функция add(), что выше, но уже с использованием анонимного объекта:

При вычислении выражения a + b, результат помещается в анонимный объект. Затем копия анонимного объекта возвращается по значению обратно в caller, и анонимный объект уничтожается.

Это работает не только с возвращаемыми значениями, но и с параметрами функции. Например, вместо этого:

Мы можем написать это:

В этом случае выражение 4 + 2 производит значение 6, которое помещается в анонимный объект. Затем копия этого анонимного объекта передаётся в функцию printResult() (которая выводит значение 6) и уничтожается.

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

Анонимные объекты класса

Хотя в примерах выше мы использовали только фундаментальные типы данных, анонимные объекты также могут использоваться и с классами. Достаточно просто не указывать имя объекта:

В примере выше строчка Dollars(8); создаст анонимный объект класса Dollars, инициализирует его значением 8, а затем уничтожит. В этом контексте пользы мы много не получим. Рассмотрим пример, где это может принести пользу:

Здесь функция main() передаёт объект dollars в функцию print(). Мы можем упростить эту программу, используя анонимные объекты:

Результат выполнения программы выше:

7 dollars.

Теперь рассмотрим пример посложнее:

В функции add() у нас есть значение sum класса Dollars, которое используется в качестве промежуточного значения для хранения результата и его возврата. И в функции main() у нас есть значение sum класса Dollars, которое также используется как промежуточное.

Можно сделать проще, используя анонимные объекты:

Эта версия функции add() идентична функции add() выше, за исключением того, что вместо отдельного объекта используется анонимный объект класса Dollars. Также обратите внимание, в main() мы больше не используем переменную с именем sum. Вместо неё мы используем возвращаемое анонимное значение из функции add()!

В результате, наша программа стала короче, чище и проще. Фактически, поскольку dollars1 и dollars2 используются только в одном месте, мы можем ещё упростить этот код с помощью анонимных объектов:

Заключение


Анонимные объекты в C++ используются для передачи или возврата значений без необходимости создания большого количества временных переменных. Динамическое выделение памяти также выполняется через анонимные объекты (поэтому адрес выделенной памяти должен быть присвоен указателю, иначе мы бы не имели способа ссылаться/использовать её).

Стоит ещё отметить, что анонимные объекты рассматриваются как r-values (а не как l-values, у которых есть адрес). Это означает, что анонимные объекты могут передаваться или возвращаться только по значению или по константной ссылке. В противном случае должна использоваться переменная.

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

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (57 оценок, среднее: 4,96 из 5)
Загрузка...

Комментариев: 6

  1. Аватар Константин:

    Как компилятор узнает, что add — это метод именно анонимного объекта Dollars, а не какого-нибудь другого класса с таким же методом. И вроде получается, что анонимный объект не инициализирован.

    1. Аватар otecart:

      Это не метод класса Dollars. Это просто функция. Среди других функций для компилятора её выделит название и принимаемые аргументы.
      А поскольку она возвращает тип Dollars, можно строить конструкции типа add(Dollars(x), Dollars(y)).getDollars(), как и для любого объекта класса Dollars.

  2. Аватар kmish:

    "В результате наша программа стала короче, чище и проще. "
    1. Короче — да.
    2. Чище — спорно:
    Не уверен, что

    чище чем

    3. Проще — уж точно не проще это читать.

    1. Аватар Александр:

      В всем должен быть баланс.

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

  3. Аватар Ануар:

    Честно, не самая трудная тема. Особенно для кого-нибудь, кто дошел до 127-ой статьи(я начал с введения в ООП).
    Я бы даже сказал интуитивно понятная тема. Если бы ты использовал это где нибудь в коде в другой теме и даже не закомментил, я бы понял. Но все равно класс.

    1. Аватар SuRprizZe:

      хахахах, "класс" в тему)))

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *