簡體   English   中英

C ++中堆類的多態性

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM