Что такое анонимный объект в С++?
Этот вопрос вводит меня в некоторое замешательство. Ведь по данному запросу гугл говорит, что анонимных объектов в С++ нет. Например, анонимные классы в 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 стандарта появилась возможность создавать лямбда-функции, это функции, не имеющие имени, их можно использовать в аргументах других функций, передавая в качестве указателя на функцию. Получается, что лямбда-функция это анонимная, безымянная функция.
Подробнее:
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Никак не могу придумать адекватный алгоритм выполнения задачи, гуглил перегуглил не нашел ничего подходящего, разве что Эйлеров путь, но это...
Хорошей практикой считается использовать DataSource вместо DriverManager'аВ спринге DataSource вообще используется очень часто
Есть матрица, нужно каждый элемент вывести на экран а также вывести его ряд и столбец