Before C++11 move()
method was implemented to avoid copying. In C++11 move semantic was introduced but sometimes it is easier to have move()
method and call its from move-constructor and moving operator=
. The move()
method can take object by normal reference (l-reference) or r-reference.
What reference should we used? What option is better/cleaner/faster/...?
Here is sample code with two possibilities (C++20 required):
#include <iostream>
#include <ranges> // copy, size
#include <memory> // unique_ptr
using namespace std;
constexpr bool MOVE_WITH_LREF_IS_BETTER = true;
class Array
{
size_t size_ = 0;
unique_ptr<int[]> data_;
public:
template<size_t N>
Array(const int (&src)[N]) : size_(N), data_(make_unique<int[]>(N))
{
std::ranges::copy(src, data_.get());
}
Array(Array&& src)
{
if constexpr(MOVE_WITH_LREF_IS_BETTER)
move_lref(src);
else
move_rref(std::move(src));
}
Array& operator=(Array&& src)
{
if constexpr(MOVE_WITH_LREF_IS_BETTER)
move_lref(src);
else
move_rref(std::move(src));
return *this;
}
void move_lref(Array& src)
{
if (&src != this)
{
size_ = exchange(src.size_, 0);
data_ = std::move(src.data_);
}
}
void move_rref(Array&& src)
{
if (&src != this)
{
size_ = exchange(src.size_, 0);
data_ = std::move(src.data_);
}
}
auto operator[](size_t index) const
{
if (index >= size_)
{
throw out_of_range("");
}
return data_[index];
}
};
int main()
{
constexpr int srcArray[] = { 1, 9, 9, 0 };
Array a(srcArray);
Array b = std::move(a);
for (size_t i=0; i < ranges::size(srcArray); ++i)
cout << b[i] << "\n";
}
Aucun commentaire:
Enregistrer un commentaire