Данный пример иллюстрирует проблему и ее решение.
Допустим, нам необходимо реализовать операции сложения и присваивания для некоторого объекта. Мы не можем использовать в качестве параметров ссылки на константу, поскольку при выполнении операций внутри каждого объекта меняет свое значение итератор. Операция сложения должна возвращать объект, созданный в стеке внутри функции. Но тогда на вход присваивания пойдет ссылка на временный объект, размещенный в стеке, что не разрешит использовать const Object& в качестве параметра присваивания. Выходом из ситуации является использование r-value ссылки.
#include <cstring> #include <utility> using namespace std; const int size=10; class Object { private: int data[size]; int iter; // моделируем использование итератора внутри объекта public: Object(int val) :iter{ 0 } { for (iter = 0; iter < size; ++iter) data[iter] = val; iter = 0; } // здесь приходится использовать ссылку на временный объект в стеке Object& operator=(Object&& obj) { for (iter = 0, obj.iter = 0; iter < size; ++iter, ++obj.iter) data[iter] = obj.data[obj.iter]; iter = 0; obj.iter = 0; return *this; } Object(Object& obj) { // нельзя использовать ссылку на константу! for (iter = 0, obj.iter = 0; iter < size; ++iter, ++obj.iter) data[iter] = obj.data[obj.iter]; iter = 0; obj.iter = 0; } Object operator+(Object& obj) { // нельзя использовать ссылку на константу! Object result(0); for (iter = 0, obj.iter = 0; iter < size; ++iter, ++obj.iter) result.data[iter] = data[iter]+obj.data[obj.iter]; iter = 0; obj.iter = 0; return result; // возвращаем объект, копируя его через стек } }; int main() { Object a{ 1 }, b{ 2 }, c{ 0 }; c = a + b; return 0; }
Комментариев нет:
Отправить комментарий