C 0x rvalue висловлювання та move-конструктор, Блог Влада Сухачова

In programming veritas

C++0x : rvalue вирази та move-конструктор

Технічно при обчисленні виразу 2+2 створюється тимчасовий об'єкт, який потім копіюється зміннуa. Для вбудованих типів це несе особливих витрат у плані продуктивності. Для користувальницьких типів, які мають ресурсомісткі операції копіювання, витрати пов'язані з викликом конструктора копіювання можуть бути суттєвими. У наступному прикладі рядку str1 надається результат конкатенації рядка str2 та str3.

В результаті операції додавання створюється тимчасовий об'єкт, який містить рядок «Hello,World!». Потім для str1 викликається оператор присвоювання, який копіює вміст тимчасового об'єкта str1. Після цього викликається деструктор видалення тимчасового об'єкта. Що станеться, якщо замість копіювання тимчасового об'єкта використовувати move семантику? Тимчасовий об'єкт все одно видаляється і ніде не використовуватиметься, тому його дані (покажчик на рядок, наприклад) можна просто привласнити відповідному полю об'єкта str1 без виклику дорогої операції копіювання. Але такий прийом допустимо лише для rvalue виразів, для lvalue так робити не можна. Отже, нам треба якимось чином розрізняти, коли оператор присвоювання викликається з lvalue виразом, а коли з rvalue.

У C++0x така можливість є. Щоб проілюструвати це прикладом, розглянемо власну реалізацію класу String з усіма необхідними методами.

Даний приклад поки не використовує можливість оптимізації оператора присвоєння для rvalue виразів. Я додав логі у виклик конструктора копіювання та оператора присвоєння.

Для такого прикладу ми отримаємо такий висновок. Copying data Copying data Першийвисновок відповідає виклику конструктора копіювання, коли виконується return tmp із оператора складання. Другий відповідає виклику оператора присвоєння. Почнемо з оператора присвоєння. Нам знадобиться написати окрему версію оператора присвоєння для rvalue виразів.

Після запуску отримуємо балку. Мов.

Висновок