Однако никаких оснований для упорядочивания здесь нет. В зависимости от того, как планируется использовать класс, определить порядок можно сначала на основании переменных revenue и units_sold. Можно было бы установить, что объекты с меньшим значением переменной units_sold были "меньше", чем таковые с большим. Либо можно было бы установить, что объекты с меньшим значением переменной-члена revenue "меньше", чем таковые с большим значением.
Для класса Sales_data нет единого логического определения значения "меньше". Таким образом, для этого класса лучше вообще не определять оператор operator<.
operator<. Но если у класса есть также оператор operator==, то определяйте оператор operator<, только если определения смысла понятий "меньше" и "равно" не противоречат друг другу.
Упражнение 14.18. Определите операторы отношения для классов StrBlob, StrBlobPtr, StrVec и String.
Упражнение 14.19. Определяет ли класс, выбранный в упражнении 7.40 раздел 7.5.1, операторы отношения? Если да, то реализуйте их. В противном случае объясните, почему нет.
14.4. Операторы присвоения
Кроме операторов присвоения копии и присваивания при перемещении, которые присваивают один объект типа класса другому объекту того же класса (см. раздел 13.1.2 и раздел 13.6.2), в классе можно определить дополнительные операторы присвоения, позволяющие использовать в качестве правого операнда другие типы.
Например, библиотечный класс vector, кроме операторов присвоения копии и присваивания при перемещении, определяет третий оператор присвоения, получающий заключенный в фигурные скобки список элементов (см. раздел 9.2.5). Этот оператор можно использовать следующим образом:
vector
v = {"a", "an", "the"};
Такой оператор можно также добавить в класс StrVec (см. раздел 13.5):
class StrVec {
public:
StrVec &operator=(std::initializer_list
//
}
Чтобы не отличаться от операторов присвоения для встроенных типов (и уже определенных операторов присвоения копии и присваивания при перемещении), новый оператор присвоения будет возвращать ссылку на левый операнд:
StrVec &StrVec::operator=(initializer_list
//
//
auto data = alloc_n_copy(il.begin(), il.end());
free(); //
elements = data.first; //
//
first_free = cap = data.second;
return *this;
}
Подобно операторам присвоения копии и присваивания при перемещении, другие перегруженные операторы присвоения должны освобождать существующие элементы и создавать новые. В отличие от операторов копирования и присваивания при перемещении, этот оператор не должен проверять случай присвоения себя себе. Параметр имеет тип initializer_list (см. раздел 6.2.6), а это означает, что объект il не может быть тем же объектом, на который указывает указатель this.
Составные операторы присвоения не обязаны быть функциями-членами. Однако все операторы присвоения, включая составные, предпочтительно определять в классе. Для согласованности со встроенными составными операторами присвоения эти операторы должны возвращать ссылку на левый операнд. Например, ниже приведено определение составного оператора присвоения для класса Sales_data.
//
//
//
Sales_data& Sales_data::operator+=(const Sales_data &rhs) {
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}