我有两个班级
class PopulationMember
{
public:
void operationOnThisMember1();
void operationOnThisMember2();
...
private:
Population* populaltion_;
}
class Population
{
public:
void operationOnAllMembers1();
void operationOnAllMembers2();
...
void operationOnAllMembers100();
void sortAllMembersCriterium1();
void sortAllMembersCriterium2();
...
void sortAllMembersCriterium100();
private:
QVector<PopulationMember*> members_;
}
我想在我的框架中实现类似SELECT的功能。这只能对那些共享特定属性组合的成员执行操作。
到目前为止,我已经考虑过两种方法:
实现一个方法,该方法将返回由满足特定条件的成员组成的新Population对象。
Popuation Popuation::select(bool (predicate*) (PopulationMember*));
添加
bool selected_;
标记每个人口成员。
如果我这样做1.无法实现所选数据的排序和删除。如果我这样做2.有检查选择性的开销,我将不得不重新实现排序和其他算法,只对选定的成员进行操作。
还有第三种更好的方式吗?
答案 0 :(得分:2)
我将采用的方法是将迭代器接口暴露给整个集合。为了实现某种选择,我将使用迭代器适配器,例如:一个采用一元谓词,提供范围的新视图。这样,既不会对存储的对象产生影响,也不会对创建单独的集合产生任何开销。如果你看看Boost的迭代器适配器,你可能已经得到了所需的东西。
答案 1 :(得分:1)
我从未看过,但我希望它是方法1.请参阅MySQL source code以确认我的期望。 : - )
答案 2 :(得分:1)
这是一个基于我曾经做过的类似事情的提议,这是你第一种方法的扩展形式。 优点是使用STL的概念,并且可以自由地实现许多仿函数或几个可参数化的仿函数。
class All
{
public:
bool operator()(const PopulationMember* entity) const
{
return true;
}
};
class AscByID
{
public:
bool operator()(const PopulationMember* a, const PopulationMember* b) const
{
return a->getId() < b.getId();
}
};
template<typename Entity, class Predicate, class SortComparator>
class Query
{
public:
typedef std::set<Entity, SortComparator> ResultSet;
Query(const Predicate& predicate = Predicate(), const SortComparator& cmp = SortComparator()) :
predicate(predicate), resultSet(cmp)
{
}
bool operator()(const Entity& entity)
{
if (predicate(entity))
{
resultSet.insert(entity);
return true;
}
return false;
}
const ResultSet& getResult(void) const
{
return resultSet;
}
void clearResult(void)
{
resultSet.clear();
}
private:
Predicate predicate;
ResultSet resultSet;
};
int main()
{
Query<const PopulationMember*, All, AscByID> query;
Popuation::execute(query);
//do something with the result
query.getResult();
//clear the result
query.clearResult();
//query again
Popuation::execute(query);
//do something useful again
return 0;
}