对于类X和QSet< X *&gt ;,如何确保QSet不包含重复元素? X类型的每个对象中的唯一属性是可以使用getName()获取的QString。
我已经实现了qHash(X *)函数,运算符==(),运算符<()和运算符>(),但QSet仍然接受重复元素,即具有相同名称的元素。
有人可以帮助我完成这项工作吗?
确定。这就是我想要做的。 我有一个Y类和一个X类,它们都继承了QDialog。类Y(槽)中的函数负责生成类X的对象.Y的对话框负责生成的X对象。这就是为什么我创建了一个QSet< X *> Y的成员。
答案 0 :(得分:3)
问题是你不能像这样重载operator==
:
bool operator==(X*, X*);
这是因为至少有一个参数必须是类类型。
既然你说你实现了operator==
,我想你做了这样的事情:
struct X
{
bool operator==(X*) const;
};
当QSet
尝试复制重复项时,永远不会调用此运算符,因为它需要类型为X
的左参数和类型为X*
我可以看到这个问题的两种可能的解决方案:
QSet<X>
)。这将允许您重载正确的运算符。然而,这种解决方案并不总是可行的。QSet
中存储指针,而不需要重载任何运算符和qHash
函数。 编辑:如果您的设计允许创建多个X
- 具有相同ID的对象,但您只想在任何时候存在一个此类对象,那么最好使用{ {1}}从id映射到QMap
。创建新对象时,请执行以下操作:
X*
答案 1 :(得分:0)
根据您的具体要求,您可以将已排序的向量与std :: unique一起使用(它接受自定义二进制谓词进行比较)。
答案 2 :(得分:0)
您可以使用QMap吗?您的对话框将包含成员变量QMap<QString, X*> items
。然后检查和创建新的X将是:
QString name = "foo";
if (!items.contains(name))
{
items[name] = new X(name);
}
else
{
// "foo" already exists
}
也许这不像使用QSet那样优雅,但我认为这更短,更容易理解。
答案 3 :(得分:-1)
我得到完全相同的问题。最后我到了这里。我的解决方案非常简单。 如果类QSet不能做我想要的,为什么不在我的类中使用它,并为我需要的每个函数添加代码。这是我的解决方案:
Set类声明:
#pragma once
#include<Plant.h>
#include<qset.h>
class Set
{
public:
Set(void);
~Set(void);
bool contains(Plant *plant);
QSet<Plant*>::iterator insert(Plant *plant);
QSet<Plant*>::iterator erase(Plant *plant);
private:
QSet<Plant*> plants;
};
Set类的定义
#include "Set.h"
Set::Set(void){
plants = QSet<Plant*>();
}
Set::~Set(void){
}
bool Set::contains(Plant *plant){
for(int i=0;i<plants.size();++i){
if(plants.values().at(i)->compare(plant))
return true;
}
return false;
}
QSet<Plant*>::iterator Set::insert(Plant *plant){
if(!contains(plant))
return plants.insert(plant);
}
QSet<Plant*>::iterator Set::erase(Plant *plant){
QSet<Plant*>::iterator it;
for(it = plants.begin();it!=plants.end();++it){
if((*it)->compare(plant)){
return plants.erase(it);
}
}
return it;
它非常适合我。