从效率角度来看,看起来不错,但包含大量重复代码。 ID
- 实施一个
swap()
您的班级的运算符。
- 初始化
length_
and data_
它们被声明的地方。
- 尽可能根据其他操作实施操作。
You might想要使用std::memcpy
代替std::copy
因为无论如何你都在处理原始数组。有些编译器会为你做这件事,但可能不是全部......
这是代码的去重版本。注意如何只有one需要知道两个实例如何的地方Widget
被交换。并且只有one知道如何分配给定大小的 Widget 的地方。
Edit:您通常还希望使用依赖于参数的查找来定位交换,以防万一您有非原始成员。
Edit:集成@Philipp关于让赋值运算符按值获取参数的建议。这样,它既充当移动赋值运算符又充当复制赋值运算符。在搬家的情况下,不是说如果你通过了临时的,won't被复制,因为移动构造函数,not复制构造函数将用于传递参数。
Edit:C++11 允许在右值上调用非成本成员,以与标准的早期版本兼容。这允许奇怪的代码,例如Widget(...) = someWidget
编译。制作operator=
需要一个左值this
通过把&
声明后可以防止这种情况发生。请注意,即使没有该限制,代码也是正确的,但它看起来仍然是一个好主意,所以我添加了它。
Edit:正如 Guillaume Papin 指出的那样,析构函数应该使用delete[]
而不是普通的delete
。 C++ 标准要求通过以下方式分配内存new []
通过删除delete []
,即它允许new' and
new []` 使用不同的堆。
class Widget
{
public:
Widget(int length)
:length_(length)
,data_(new int[length])
{}
~Widget()
{
delete[] data_;
}
Widget(const Widget& other)
:Widget(other.length_)
{
std::copy(other.data_, other.data_ + length_, data_);
}
Widget(Widget&& other)
{
swap(*this, other);
}
Widget& operator= (Widget other) &
{
swap(*this, other);
return *this;
}
int length() const
{
return length_;
}
private:
friend void swap(Widget& a, Widget& b);
int length_ = 0;
int* data_ = nullptr;
};
void swap(Widget& a, Widget& b) {
using std::swap;
swap(a.length_, b.length_);
swap(a.data_, b.data_);
}