[英]Polymorphism for heap classes in C++
假设我有一个像这样的Rectangle
类:
class Rectangle {
public:
double width;
double height;
}
现在,我希望将两个可能不同的Rectangles
列表存储为堆,除了第一个堆应基于width
,第二个堆应基于height
。 另外,我希望使用stl的make_heap
函数进行堆化。 理想情况下,我应该能够在堆上调用.heapify()
,并且基于它所属的类,所讨论的堆应该通过将正确的比较函数传递给make_heap
,也许可以使用动态分配。 我有以下内容:
class Heap {
public:
vector<Rectangle> data;
virtual bool comp(Rectangle a, Rectangle b);
void heapify() { make_heap(data.begin(), data.end(), comp); }
// other methods that make use of comp directly
}
class WidthHeap : public Heap {
bool comp(Rectangle a, Rectangle b); // compares by width
}
class HeightHeap : public Heap {
bool comp(Rectangle a, Rectangle b); // compares by height
}
这都是错误的,因为我想我只是不了解C ++中的函数,这就是为什么我需要您的帮助。
因为comp
是成员函数指针,所以不传递this
不能调用this
。 您需要this
绑定到它:
std::make_heap(data.begin(), data.end(), std::bind(&Heap::comp, this, _1, _2));
std::bind
可以在C ++ 11的<functional>
标头中找到,也可以使用TR1在<tr1/functional>
std::tr1::bind
中使用。 如果您不能使用TR1或C ++ 11,则可以使用Boost库 。
演示: http : //ideone.com/5zhmg
除了绑定之外,另一种解决方案是简单地要求将指向函数的指针传递给Heap
的构造函数。
// C++03
typedef bool (*CompType)(Rectangle const&, Rectangle const&);
// C++11 (to allow for lambdas and predicates)
typedef std::function<bool(Rectangle const&, Rectangle const&)> CompType;
接着:
class Heap {
public:
explicit Heap(CompType cmp): cmp(cmp) {}
void heapify() {
std::make_heap(data.begin(), data.end(), cmp);
}
private:
CompType cmp;
std::vector<Rectangle> data;
}; // class Heap
有趣的是,您甚至可以走得更远,并在一点点想象力的情况下同时保持两个订单。
class Heap {
public:
Heap():
byLength([](Rectangle const& l, Rectangle const& r) {
return l.length < r.length; }),
byWidth[](Rectangle const& l, Rectangle const& r) {
return l.width < r.width; }),
{}
void heapify() {
std::make_heap(data.begin(), data.end(), byLength);
std::make_heap(ref.begin(), ref.end(),
[](Rectangle const* l, Rectangle const* r) {
return byWidth(*l, *r);
});
}
private:
CompType byLength;
CompType byWidth;
std::vector<Rectangle> data;
std::vector<Rectangle*> ref;
}; // class Heap
虽然...可能有点矫kill过正;)
您正在传递成员函数。 成员函数具有this
指针。 make_heap
函数应从make_heap
获取?
具体来说,使用以下语法(对于本发明的类X
)调用成员函数的指针:
X* obj_ptr; // initialize somewhere
typedef void (X::*mem_ptr)();
mem_ptr mem_fun = &X::some_invented_function;
(obj_ptr->*mem_fun)(); // extra parens needed
obj_ptr
是缺少make_heap
函数的内容。 您以某种方式需要提供它,最简单的方法可能是通过C ++ 11中的lambda:
std::make_heap(data.begin(), data.end(),
[this](Rectangle r1, Rectangle r2){
return comp(r1,r2);
});
或者甚至std::bind
:
#include <functional>
using std::placeholders;
std::make_heap(data.begin(), data.end(), std::bind(&X::comp, this, _1, _2));
如果您无权使用这些C ++ 11功能,请使用Boost.Bind 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.