在QSet中重复

时间:2010-08-15 21:20:33

标签: c++ qt qt4 set duplicates

对于类X和QSet< X *&gt ;,如何确保QSet不包含重复元素? X类型的每个对象中的唯一属性是可以使用getName()获取的QString。

我已经实现了qHash(X *)函数,运算符==(),运算符<()和运算符>(),但QSet仍然接受重复元素,即具有相同名称的元素。

有人可以帮助我完成这项工作吗?


确定。这就是我想要做的。 我有一个Y类和一个X类,它们都继承了QDialog。类Y(槽)中的函数负责生成类X的对象.Y的对话框负责生成的X对象。这就是为什么我创建了一个QSet< X *> Y的成员。

4 个答案:

答案 0 :(得分:3)

问题是你不能像这样重载operator==

bool operator==(X*, X*);

这是因为至少有一个参数必须是类类型。

既然你说你实现了operator==,我想你做了这样的事情:

struct X
{
    bool operator==(X*) const;
};

QSet尝试复制重复项时,永远不会调用此运算符,因为它需要类型为X的左参数和类型为X*

的权限

我可以看到这个问题的两种可能的解决方案:

  • 不要将您的商品存储为指针(即使用QSet<X>)。这将允许您重载正确的运算符。然而,这种解决方案并不总是可行的。
  • 如果你能以某种方式强制执行只有一个具有给定id的对象,你可以只在你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;

它非常适合我。