multiset的使用

23 篇文章 0 订阅
使用环境VC2010

一. 简单使用

"代码1"

struct STItem
{
	STItem();
	STItem(const STItem& stItem);
	~STItem();
	STItem(int nData);
	STItem& operator=(const STItem& stItem);
	void Release();
	int m_nData;
};


class CItemCmp
{
public:
	// 这个必须定义和实现
	bool operator()(const STItem& stItemA,const STItem& stItemA) const
	{
		// 在这个函数里面, 你喜欢怎样比较都行.
		return stItemA.m_nData < stItemA.m_nData;
	}
};
// CItemCmp很明显就是作为一个类似"函数对象"的角色
typedef std::multiset<STItem, CItemCmp> STItemMultiset;
typedef STItemMultiset::iterator STItemMultisetIterator;


// 使用
STItemMultiset itemMultset;
itemMultset.insert(STItem(1));
itemMultset.insert(STItem(2));
itemMultset.insert(STItem(5));
itemMultset.insert(STItem(8));
itemMultset.insert(STItem(9));
itemMultset.insert(STItem(6));
itemMultset.insert(STItem(1));
itemMultset.insert(STItem(4));
itemMultset.insert(STItem(2));


// itemMultset最终会得到排序
// 按照STItem.m_nData的升序排列
// 1, 1, 2, 2, 4, 5, 6, 8, 9



二. 遇到问题

上面例子中STItem是以对象形式存储在multiset容器中的, 如果STItem是一个比较大的对象的话, multiset内部的内存拷贝很频繁, 效率底下. 
解决方法很简单, 使用指针.

"代码2"

struct STItem
{
	STItem();
	STItem(const STItem& stItem);
	~STItem();
	STItem(int nData);
	STItem& operator=(const STItem& stItem);
	void Release();
	int m_nData;
};


class CItemCmp
{
public:
	// 这里参数使用指针
	bool operator()(const STItem*& pSTItemA,const STItem*& pSTItemA) const
	{
		// 在这个函数里面, 你喜欢怎样比较都行.
		return pSTItemA->m_nData < pSTItemA->m_nData;
	}
};
// 这里需要改变
typedef std::multiset<STItem*, CItemCmp> STItemMultiset;
typedef STItemMultiset::iterator STItemMultisetIterator;


// 使用
STItemMultiset itemMultset;
itemMultset.insert(new STItem(1));	// 这里需要改变


但是这样修改, 编译没通过. (我个人的理解: 参照"代码1", 依葫芦画瓢, 得到的"代码2"应该是可行的, 但实际上编译报错了).
报错是 关于bool operator()(const STItem*& pSTItemA,const STItem*& pSTItemA) const 
中STItem* 不能转换为 const STItem*& 之类的.

可能是我自己在指针, 常量指针上的理解不透彻吧.


三. 走一点弯路来解决

"代码3"

struct STItem
{
	STItem();
	STItem(const STItem& stItem);
	~STItem();
	STItem(int nData);
	STItem& operator=(const STItem& stItem);
	void Release();
	int m_nData;
};


// 增加这个中间类
// 这个类里面管理STItem的指针, 在外面提供给CItemCmp类的operator()函数的参数作为引用使用.
class CSTItem
{
public:
	CSTItem(STItem* pSTItem)
	{
		m_pSTItem = pSTItem;
	}
	CSTItem()
	{
		m_pSTItem = 0;
	}
	CSTItem(const CSTItem& cSTItem)
	{
		*this = cSTItem;
	}
	~CSTItem()
	{
		m_pSTItem = 0;
	}


	CSTItem& operator=(const CSTItem& cSTItem)
	{
		m_pSTItem = cSTItem.m_pSTItem;
		return *this;
	}
	STItem* m_pSTItem;
};




class CItemCmp
{
public:
	// 这里参数使用指针
	bool operator()(const CSTItem& pCSTItemA,const STItem*& pCSTItemA) const
	{
		// 在这个函数里面, 你喜欢怎样比较都行.
		// 多了一层指针引用
		return pCSTItemA->m_pSTItem->m_nData < pSTItemCmpA->m_pSTItem->m_nData;
	}
};
// 这里需要改变
typedef std::multiset<CSTItem, CItemCmp> CSTItemMultiset;
typedef CSTItemMultiset::iterator CSTItemMultisetIterator;


// 使用
CSTItemMultiset itemMultset;
itemMultset.insert(CSTItem(new STItem(1)));	// 这里需要改变

路走弯了一点, 合适就好.


感觉"代码2"是可行的, 差一点点.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值