I saw many code implementing rule of five in terms of copy and swap, but I think we can use a move function to replace the swap function as in the following code:
#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_;
};
This code, I think
- Exception safe
- Require less typing, as many function just call move_to_this(), and copy assignment and move assignment are unified in one single function
- More efficient than copy-and-swap, as swap involves 3 assignments, while here just 2, and this code doesn't suffer the problems mentioned in This Link
Am I right?
Thanks
Edit:
- As @Leon pointed out, maybe a dedicated function for freeing resource is needed, to avoid code duplication in
move_to_this()
and destructor As @thorsan pointed out, for extreme performance concern, it's better to seperateDumbArray& operator=(DumbArray that) { move_to_this(that); return *this; }
intoDumbArray& operator=(const DumbArray &that) { DumbArray temp(that); move_to_this(temp); return *this; }
(thanks to @MikeMB) andDumbArray& operator=(DumbArray &&that) { move_to_this(that); return *this; }
to avoid an extra move operatoinAfter adding some debug print, I found that no extra move is involved in
DumbArray& operator=(DumbArray that) {}
when you call it as a move assignmentAs @Erik Alapää pointed out, a self-assignment check is needed before
delete
inmove_to_this()