std :: set的有效比较函数

时间:2012-10-20 05:03:58

标签: c++ set std

我正在研究一个简单的图形引擎,我有Drawable对象,它们应该在创建时(在构造函数中)将自己注册到Renderer(通过将它们插入到集合中)。它们还需要进行排序(通过透明度,深度掩码等),即它们需要按一些布尔标记排序。

所以这是我的设置。

std::set<Drawable *, DrawableComp> drawable_set;

比较函子:

struct DrawableComp : public std::binary_function<const Drawable *, const Drawable *, bool> {
    bool operator() (const Drawable * lhs, const Drawable * rhs) const
    {
        return *lhs < *rhs;
    }
};

重载运算符&lt;可绘制的:

bool Drawable::operator<(const Drawable & rhs) const
{
    if (writesDepth() != rhs.writesDepth())
        return !writesDepth() < !rhs.writesDepth();
    else
        return getSortNumber() < rhs.getSortNumber();
}

注意,这应该按顺序将Drawables插入到set中,以便先写入深度缓冲区的对象,然后再写入不写入深度缓冲区的对象。每个对象的排序编号都是唯一的。

问题是,这不起作用。我得到Drawables,在set的末尾写入深度缓冲区。

另外,writeDepth()是虚拟bool函数。 Drawable只是一个抽象的接口。如果我使writeDepth()纯虚拟,我得到运行时错误“纯虚方法调用”。我不清楚为什么会这样,因为我从来没有将Drawable对象放在set中,而是将其具体实现。

1 个答案:

答案 0 :(得分:0)

好的,我发现了问题。我正在从Drawable构造函数中注册Drawables。我在构造函数中调用了这个(registerDrawable只是插入到set中):

Application::get().getRenderer().registerDrawable(this);

问题是这会发送指向Drawable类型的对象而不是某些派生类型的指针,因此设置“不知道”派生类是什么,它只调用基本方法writeDepth()。

简单的解决方案是将此调用移动到派生构造函数。虽然它在我的设计中插入了一点点麻烦和冗余......