Я видел много правил реализации кода пять в терминах копирования и свопинга, но я думаю, что мы можем использовать функцию перемещения для замены функции свопинга, как в следующем коде:
#include <algorithm>
#include <cstddef>
class DumbArray {
public:
DumbArray(std::size_t size = 0)
: size_(size), array_(size_ ? new int[size_]() : nullptr) {
}
DumbArray(const DumbArray& that)
: size_(that.size_), array_(size_ ? new int[size_] : nullptr) {
std::copy(that.array_, that.array_ + size_, array_);
}
DumbArray(DumbArray&& that) : DumbArray() {
move_to_this(that);
}
~DumbArray() {
delete [] array_;
}
DumbArray& operator=(DumbArray that) {
move_to_this(that);
return *this;
}
private:
void move_to_this(DumbArray &that) {
delete [] array_;
array_ = that.array_;
size_ = that.size_;
that.array_ = nullptr;
that.size_ = 0;
}
private:
std::size_t size_;
int* array_;
};
Этот код, я думаю,
- Безопасное исключение
- Требовать меньше ввода, так как многие функции просто вызовут move_to_this(), а назначение копирования и назначение переноса объединены в одну единственную функцию
- Более эффективный, чем копирование и своп, поскольку своп включает в себя 3 назначения, а здесь всего 2, и этот код не страдает проблемами, упомянутыми в Эта ссылка
Я прав?
Спасибо
Edit:
- Как отметил @Leon, может потребоваться выделенная функция для освобождения ресурса, чтобы избежать дублирования кода в
move_to_this()
и destructor -
Как отметил @thorsan, для экстремальной производительности лучше отделитьDumbArray& operator=(DumbArray that) { move_to_this(that); return *this; }
доDumbArray& operator=(const DumbArray &that) { DumbArray temp(that); move_to_this(temp); return *this; }
(благодаря @MikeMB) иDumbArray& operator=(DumbArray &&that) { move_to_this(that); return *this; }
, чтобы избежать дополнительного перемещения operatoinПосле добавления отладочной печати я обнаружил, что в
DumbArray& operator=(DumbArray that) {}
не задействован дополнительный ход, когда вы называете это назначением перемещения -
Как отметил @Erik Alapää, перед
необходима проверка самонаведенияdelete
вmove_to_this()