用C ++设计一个可以多种方式进行比较的对象

时间:2012-03-17 20:58:59

标签: c++ sorting comparison

假设我们有一个代表一个盒子的对象。

class Box {
  public:
    int length;
    int width;
    int height;

    Box(int l, int w, int h);
    ~Box();
    int area(const int l, const int w) const;
    int volume(const int l, const int w, const int h) const; 
};

现在让我们说在另一个类中,在另一个文件中,我们有std::list<Box>包含n个框。我们希望以不同的方式显示这些盒子的打印件。

  • 首先,我们希望按照长度增加的顺序打印出来。
  • 然后我们想要按照宽度增加的顺序将它们打印出来。
  • 我们现在不关心他们的高度,但也许以后我们会。

现在std::list有一个成员函数sort(),它将比较函数作为参数。我们如何改变上面的Box类,以便我们可以使用不同的比较函数调用列表中的sort()

更具体地说,我们可以在box类中定义三个不同的函数,并将它们简单地传递给list.sort()吗?在类之外全局定义比较函数是否更好直观地将它们绑定到类似乎更好但为什么不是这种情况?总的来说,实现这一目标的“最佳”方式是什么?

6 个答案:

答案 0 :(得分:3)

如果你真的想实施三种不同的比较 作为成员的操作你可以做这样的事情:

struct Box {
  int x, y, length;

  bool less_by_x(const Box& other) { return this.x < other.x; }
  bool less_by_y(const Box& other) { return this.y < other.y; }
  bool less_by_length(const Box& other) { return this.y < other.y; }
};

并像这样使用它们:

#include <functional>
// you probably shouldn't be using a list anyway
std::list<Box> l; 
l.sort(std::mem_fun_ref(&Box::less_by_x));

mem_fun_ref返回一个二进制函数对象,该对象接受对该函数所属的类的引用以及所有其余参数(仅在C ++ 11中,这仅限于C中的二进制函数) ++ 03)成员函数。

虽然实施比较似乎更合理 作为自由职能的运作。

答案 1 :(得分:1)

您必须提供比较器功能(或功能对象)。例如:

bool my_sort_function (const Box& box1, const Box& box2)
{
        // use some criteria and return a boolean (true if box1 goes before box2)
        // ...
}

然后按以下方式调用sort ()方法:

my_list.sort (my_sort_function);

答案 2 :(得分:0)

如果您想将成员函数作为参数传递,那么最好的选择是使用boost::mem_fn

答案 3 :(得分:0)

std::list::sort()接受比较函数对象,该对象允许您定义自定义排序条件。这可以是普通函数(自由函数或静态成员)或具有兼容operator()的类的实例。有关详细信息和示例,请参阅some documentation

答案 4 :(得分:0)

标准C ++库中的各种排序函数采用比较对象。这些可能包含他们需要的任何数据。它们的关键要求是它们是可复制的,并且它们的函数调用操作符在应用于其参数类型的对象时会产生严格的弱序。很容易创建一个比较对象,例如,存储指向用于将对象映射到属性的成员函数的指针,特别是如果所有属性具有相同类型(如果属性具有不同类型,则事情更有趣)。有了这个,可以将相同的列表分成不同的顺序。

答案 5 :(得分:0)

执行此操作的最佳方法是为每个参数实现一个比较函数,并在调用sort时将其传递给sort。 该函数布尔比较(框a,框b)应等于&lt; b,也就是说,如果a在按参数排序时出现在b之前,则为真。