14.4 赋值运算符
赋值运算符必须定义为成员函数,返回左侧运算对象的引用
复合赋值运算符
Sales_data& Sales_data::operator+=(const Sales_data& rhs) {
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
14.5 下标运算符
表示容器的类一般会定义下标运算符operator[]
下标运算符必须是成员函数,通常定义两个版本:一个返回普通引用,另一个是类的常量成员并且返回常量引用
class StrVec {
public:
string& operator[](size_t n) {
return elements[n];
}
const string& operator[](size_t n) const {
return elements[n];
}
private:
string *element;
};
对常量对象取下标时,不能为其赋值
const StrVec cvec = svec;
if (svec.size() && svec[0].empty()) {
svec[0] = "zero"; // 正确
cvec[0] = "Zip"; // Err
}
14.6 递增和递减运算符
定义前置递增/递减运算符
class StrBlobPtr {
public:
StrBlobPtr& operator++();
StrBlobPtr& operator--();
};
前置运算符应该返回递增或递减后对象的引用
StrBlobPtr& StrBlobPtr::operator++() {
check(curr, "increment past end of StrBlobPtr");
++curr; // 将curr在当前状态下向后移动一个元素
return *this;
}
StrBlobPtr& StrBlobPtr::operator--() {
// 如果curr是0,则继续递减将产生一个无效的下标
--curr; // 将curr在当前状态下向前移动一个元素
check(curr, "decrement past begin of StrBlobPtr");
return *this;
}
区分前置和后置运算符
后置版本接受一个额外的int
类型的形参,唯一作用是区分前置版本和后置版本
class StrBlobPtr {
public:
StrBlobPtr operator++(int);
StrBlobPtr operator--(int);
};
后置运算符应该返回对象的原值(递增或递减之前的值),返回的是一个值而非引用
要先记录对象的状态
StrBlobPtr StrBlobPtr::operator++(int) {
StrBlobPtr ret = *this; // 记录当前的值
++*this; // 调用前置运算符
return ret; // 返回保存的副本
}
StrBlobPtr StrBlobPtr::operator--(int) {
StrBlobPtr ret = *this;
--*this;
return ret;
}
显式地调用后置运算符
需要传个参数给int
StrBlobPtr p(a1);
p.operator++(0); // 调用后置版本
p.operator++(); // 调用前置版本