这是一项常见任务,您必须为对象重载/覆盖或定义自定义比较运算符,例如将它们存储在 sets/unordered_sets 中或将对象用作 maps/unordered_maps 中的键。为此,您必须定义“小于”运算符(<)、等于运算符(==)和“哈希”运算符。C++ 允许以不同的方式做到这一点。我首选的方法是在您的对象内部定义它们。因此,您可以更好地了解对象行为。我创建的示例在现实世界中可能没有多大意义,但展示了定制行为的想法。
#include<assert.h>
#include<set>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<map>
using namespace std;
struct Person
{
string name;
unsigned age;
double wage;
Person() :name(""), age(0), wage(0.0) {}
Person(const string& n, unsigned a, double w) :name(n), age(a), wage(w) {}
Person & operator=(const Person& p) {
if (this == &p)
return *this;
this->name = p.name;
this->age = p.age;
this->wage = p.wage;
return *this;
}
// less than oprator for sets
bool operator<(const Person& other) const {
return this->wage < other.wage;
}
// equal oprator for maps
bool operator==(const Person& other)const {
return ((this->name == other.name) && (this->age == other.age));
}
//hash operator for unordered_sets/unordered_maps
size_t operator()(const Person& p) const {
return std::hash<string>()(p.name);
}
};
int main()
{
set<Person> personsSet;
Person a("a", 20, 3000.0), b("b", 30, 2000.0), c("c", 40, 1000.0), d("d", 25, 500.0), e("e", 31, 700.0);
personsSet.insert(a);
assert(personsSet.size() == 1);
personsSet.insert(b);
assert(personsSet.size() == 2);
personsSet.insert(c);
assert(personsSet.size() == 3);
personsSet.insert(d);
assert(personsSet.size() == 4);
personsSet.erase(b);
assert(personsSet.size() == 3);
personsSet.erase(e);
assert(personsSet.size() == 3);
map<Person, string> personsMap;
personsMap.insert({ a, "first" });
personsMap.insert({ b, "second" });
personsMap.insert({ c, "third" });
personsMap.insert({ d, "fourth" });
assert(personsMap.size() == 4);
personsMap[d] = "";
assert(personsMap[d] == "");
personsMap.erase(b);
assert(personsMap.size() == 3);
personsMap.erase(e);
assert(personsMap.size() == 3);
unordered_set<Person, Person> personUset;
personUset.insert(a);
assert(personUset.size() == 1);
personUset.insert(b);
assert(personUset.size() == 2);
personUset.insert(c);
assert(personUset.size() == 3);
auto f = personUset.find(b);
personUset.erase(f);
assert(personUset.size() == 2);
f = personUset.find(e);
assert(f == personUset.end());
unordered_map<Person, int, Person> personUmap;
personUmap[b] = 2;
assert(personUmap.size() == 1);
assert(personUmap[b] == 2);
personUmap[c] = 3;
personUmap[d] = 4;
auto mf = personUmap.find(c);
assert(mf->first == Person({"c", 40, 1000.0}));
assert(mf->second == 3);
assert(personUmap.size() == 3);
personUmap.erase(mf);
assert(personUmap.size() == 2);
personUmap.erase(e);
assert(personUmap.size() == 2);
}