前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >set中如何存储自定义对象?

set中如何存储自定义对象?

作者头像
编程珠玑
发布2020-03-11 11:40:56
1.9K0
发布2020-03-11 11:40:56
举报
文章被收录于专栏:编程珠玑

如何在set中存储自定义对象?

set是什么

假设你已经在C++中使用过set,那么你应该知道,set中存储的元素是去重的。比如:

代码语言:javascript
复制
//来源:公众号:编程珠玑
//作者守望先生
#include <iostream>
#include <set>
using namespace std;
int main()
{
    set<int> a;
    a.insert(123);
    a.insert(111);
    a.insert(111);
    a.insert(2);
    //遍历set
    for(auto &it:a)
    {
        cout<<it<<endl;
    }
    return 0;
}

输出结果:

代码语言:javascript
复制
2                                                                                                                    
111                                                                                                                  
123

虽然插入了两次111,但是最终只会存储一个,也就是最后set中只有三个元素。

如何在set中存储自定义对象

有时候,我们可能想通过set做一下去重的事情,对于基本数据类型,set都能很好地处理。我们看看对于自定义的对象,它的结果如何呢?

代码语言:javascript
复制
//来源:公众号【编程珠玑】
//作者:守望先生
#include <iostream>
#include <set>
using namespace std;
class MyObject
{
    //方便起见,暂时设置为public
    public:
        int id;
        string data;
    public:
        MyObject(int i,string d):id(i),data(d){}
};
int main()
{

    set<MyObject> a;
    a.insert(MyObject(123,"123"));
    a.insert(MyObject(111,"111"));
    a.insert(MyObject(111,"111"));
    a.insert(MyObject(2,"2"));
    for(auto &it:a)
    {
        cout<<it.id<<endl;
    }
    return 0;
}

很不幸,还没来得及运行,先报错了。

代码语言:javascript
复制
error: no match for ‘operator<’ (operand types are ‘const MyObject’ and ‘const MyObject’)

从报错信息我们可以推断出,它是需要调用‘operator<’,也就是说,我们需要重载操作符<,让它可以用来判断元素是否重复。那么重载它有什么原则呢? 关于操作符的重载,可以参考《什么是运算符的重载?》。

重载原则

注意,这里是仅仅介绍去重时的原则,这里暂时未涉及排序。准则细看有很多,这里总结起来就是: 两个元素如果没有任何一个小于另外一个,则他们视为重复。 假设比较函数是f(x,y),那么当f(x,y)和f(y,x)都返回false的时候,认为他们是重复的。

调用原则

其实,set容器在判定已有元素a和新插入元素b是否相等时,是这么做的:

  • 将x作为左操作数,y作为右操作数,调用比较函数,并返回比较值
  • 将x作为左操作数,y作为右操作数,再调用一次比较函数,并返回比较值。 如果他们两个都返回false,则认为重复,重复的元素不会被插入到容器中。

当然需要注意的是,如果x<y为true,那么x>y应为false,所以这里应该避免两个都返回true,否则将会出现未知行为。

参考实现

对于我们前面的例子来说,假设id重复,则认为对象是相同的,那么重载的<参考实现如下:

代码语言:javascript
复制
  bool operator<(const MyObject &a) const
    {
        if(this->id == a.id)
        {
            return false;
        }
        else
        {
            return this->id > a.id;
        }
    }

添加之后,重新运行,就符合预期,可以对自定义对象去重啦!

总结

对于自定义对象存储在set中,如果我们希望它按照我们指定的规则去重,就可能需要重载operator<了,那么是不是只有这一种方法呢?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程珠玑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • set是什么
  • 如何在set中存储自定义对象
  • 重载原则
  • 调用原则
  • 参考实现
  • 总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档