在实现 C++11move()
方法以避免复制之前。move()
在 C++11 中引入了 move 语义,但有时拥有方法并从 move-constructor 和 move 调用它更容易operator=
。该move()
方法可以通过普通引用(l-reference)或r-reference来获取对象。
我们应该使用什么参考?哪个选项更好/更清洁/更快/...?
这是具有两种可能性的示例代码(需要 C++20):
#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";
}