Что такое анонимный объект в С++?
Этот вопрос вводит меня в некоторое замешательство. Ведь по данному запросу гугл говорит, что анонимных объектов в С++ нет. Например, анонимные классы в c++. И тут же, цитата с MSDN:
Лямбда-выражение (или просто лямбда) в C++11 — это удобный способ определения анонимного объекта-функции.
Возможно, далее представлено не то, что вам нужно, но пройдусь по терминологии.
Непосредственно термина "анонимный объект" в C++ нет. Но есть "безымянный объект" (unnamed object). Данный термин в таком виде встречается в черновике стандарта n4750 всего лишь раз в разделе про "анонимные объединения" (anonymous unions) 12.3.1/1:
A union of the form union { member-specification } ;
is called an anonymous union; it defines an unnamed type and an
unnamed object of that type called an anonymous union object.
Пример оттуда же с моими комментариями:
void f() {
union { int a; const char* p; }; // определяется безымянный объект типа объединение
a = 1; // несмотря на то, что `a` и `p` используются как обычные переменные ...
p = "Jennifer"; // ... они, тем не менее, являются членами безымянного объекта
}
Но есть и другие ситуации, например, безымянный объект можно получить, вызвав конструктор вида T() или вызвав функцию, возвращающую некий тип.
struct T() {};
T f() { T t; return t; }
T(); // создаёт безымянный объект
f(); // возвращает безымянный объект
Создание объекта через new T - это то же самое, что T(), только с размещением в куче, а не на стеке. И бесконечным временем жизни, ведь если для указателя, который вернул new не вызвать delete, мы получим утечку памяти. Безымянный объект, созданный на стеке, будет разрушен после ближайшей ;.
В языке c++ есть понятие lvalue и rvalue. Если совсем просто, lvalue это нечто, имеющее имя, а значит это "нечно" может быть слева в операторе присваивания, например:
int x;
x = 10;
Здесь объект x это lvalue, и мы можем присваивать "в него". Он также имеет имя "x", при этом не следует путать имя (в данном случае "x") и значение (сразу после определения оно скорее всего не определено, после присвоения значение будет 10). Обратите внимание, что "имя", о котором идёт речь, присутствует только на этапе компиляции. Также наличие имени обязывает разместить компилятор в какой-нибудь памяти, и значит, имеет смысл понятие адреса этого объекта (проще говоря, указатель).
Насчёт rvalue , тут всё похоже. Объект, не имеющий имени, это rvalue, пример:
int x;
x = 10;
Здесь 10 это rvalue типа int, если мы попытаемся в него присвоить что-нибудь: 10 = x; , то получим ошибку компиляции. Rvalue могут быть "справа" в операторе присваивания, но не могут быть слева. Объект rvalue существует, но его адрес не имеет смысла (может вообще не существовать, потому что, к примеру, компилятор может его разместить в регистре, или вообще заоптимизировать).
Теперь насчёт функций. В языке Си, и в C++ до 11 стандарта, если вам была необходима некоторая функция, вы обязательно объявляли её прототип, и описание. В прототипе вы давали функции имя. Это аналог lvalue для функций, у вас есть функция с конкретным наименованием. С 11 стандарта появилась возможность создавать лямбда-функции, это функции, не имеющие имени, их можно использовать в аргументах других функций, передавая в качестве указателя на функцию. Получается, что лямбда-функция это анонимная, безымянная функция.
Подробнее:
Сборка персонального компьютера от Artline: умный выбор для современных пользователей