Данный пример иллюстрирует проблему и ее решение.
Допустим, нам необходимо реализовать операции сложения и присваивания для некоторого объекта. Мы не можем использовать в качестве параметров ссылки на константу, поскольку при выполнении операций внутри каждого объекта меняет свое значение итератор. Операция сложения должна возвращать объект, созданный в стеке внутри функции. Но тогда на вход присваивания пойдет ссылка на временный объект, размещенный в стеке, что не разрешит использовать 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;
}
Комментариев нет:
Отправить комментарий