我正在研究一个简单的图形引擎,并且我有Drawable对象,在创建时(在构造函数中),它们应该将自己注册到Renderer(通过将它们插入集合中)。它们还需要进行排序(通过透明度,深度遮罩等),即它们需要通过一些布尔标志进行排序。std :: set的有效比较函数
所以这里是我的设置。
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;
}
};
和重载操作<:
bool Drawable::operator<(const Drawable & rhs) const
{
if (writesDepth() != rhs.writesDepth())
return !writesDepth() < !rhs.writesDepth();
else
return getSortNumber() < rhs.getSortNumber();
}
注意,这应该可绘制插入的顺序设置,这样第一次去那个写对象到深度缓冲区,然后是那些不写入深度缓冲区的深度缓冲区。排序号码对每个对象都是唯一的。
问题是,这是行不通的。我在Draw集合的末尾写入深度缓冲区的Drawables。
此外,writeDepth()是虚拟布尔函数。 Drawable只是一个抽象接口。如果我写writeDepth()纯虚拟,我得到运行时错误“纯虚方法调用”。我不清楚为什么会这样,因为我从来没有将Drawable对象设置为集合,而是将其具体实现。
只要您创建'writesDepth()'pure,就会得到_pure虚拟方法called_,这一事实表明至少有一个派生类不会覆盖方法。这可能是导致排序顺序错误的原因(派生类的所有实例将被错误地排序,因为它们的writesDepth()方法不存在,因此会退回到返回错误值的基类方法)。那可能吗? – jogojapan
这不是我想的。我尝试了打印和放置断点。我有两个Drawable实现。 writeDepth()实现和Drawable接口被调用。 –
接口的'writeDepth()'也被调用?然后,无论是从派生类中调用它(是吗?),或者必须至少有一个派生实现不能正确覆盖它。你可以为这两个派生类发布'writeDepth()'的代码吗?也许他们没有被正确覆盖。 – jogojapan