拷贝赋值
我们可以通过构造函数拷贝(初始化)对象,但我们也可以通过赋值的方式拷贝vector。
拷贝术语
<<是输入运算符,就是将大头的那边的量弄进箭头所指的对象中,并返回运算之后的箭头所指的对象
移动
vector fill(istream& is)
{
vector res;
for(double x; is>>x;) res.push_back(x);
return res;
}
void use()
{
vector vec = fill(cin);
}
class vector
{
int sz;
double* elem;
public:
vector(vector&&a); //移动构造函数
vector& operator=(vector&&); //移动赋值
//..
}
滑稽的&&符号被称为“右值引用”。我们用它来定义移动操作。注意,移动操作不接
受const参数;即,我们应使用(vector&&)而不是(const vector&&)。
移动操作的目的之一是修改源对象,令其变为“空的”。移动操作的定义应该更简单,应该比
对应的拷贝操作更简单高效。
vector::vector(vector&& a)
:sz{a.sz},elem{a.elem} // 拷贝a的elem和sz
{
a.sz = 0; //令a变为空vector
a.elem = nullptr;
}
vector& vector::operator=(vector&& a)//将a移动到本vector
{
delete[] elem; //释放旧空间
elem = a.elem; //拷贝a的elem和sz
az = a.sz;
a.elem = nullptr; //令a变为空vector
a.sz = 0;
return *this; //返回一个自引用
}
vector fill(istream& is)
{
vector res;
for(double x; is>>x;) res.push_back(x);
return res;
}
移动构造函数隐式地用于实现函数返回。编译器知道要返回的局部值(res)将要离开
其作用域,因此可以将其值移动出而非拷贝它。
移动构造函数的重要性在于我们不必为了从一个函数返回大量信息而处理指针或引用。
下面这种有瑕疵的替代方法:
vector* fill2(istream& is)
{
vecotor* res = new vector;
for(double x; is>>x;) res->push_back(x);
return res;
}
void use2()
{
vector* vec = fill(cin);
//...
}
若采用这种方法,我们就必须记得释放vector.释放自由空间上的对象并不像看起来那么容易实现一致性和正确性。