对指针列表进行排序

Yup*_*ing 6 c++ sorting pointers stl

我再一次发现自己在C++中完成了一些非常简单的任务.有时候我希望我可以在java中从OO中学习我所知道的所有内容,因为我的问题通常都是从Java开始思考.

无论如何,我有一个std::list<BaseObject*>我想要排序的.让我们说BaseObject是:

class BaseObject {
protected:
    int id;
public: 
    BaseObject(int i) : id(i) {};
    virtual ~BaseObject() {};
};
Run Code Online (Sandbox Code Playgroud)

我可以BaseObject使用比较器结构对指针列表进行排序:

struct Comparator {
    bool operator()(const BaseObject* o1, const BaseObject* o2) const {
        return o1->id < o2->id;
    }
};
Run Code Online (Sandbox Code Playgroud)

它看起来像这样:

std::list<BaseObject*> mylist;
mylist.push_back(new BaseObject(1));
mylist.push_back(new BaseObject(2));
// ...

mylist.sort(Comparator()); 

// intentionally omitted deletes and exception handling
Run Code Online (Sandbox Code Playgroud)

直到这里,一切都很好.但是,我介绍了一些派生类:

class Child : public BaseObject {
    protected:
    int var;
    public: 
    Child(int id1, int n) : BaseObject(id1), var(n) {};
    virtual ~Child() {};
};

class GrandChild : public Child {
    public:
    GrandChild(int id1, int n) : Child(id1,n) {};
    virtual ~GrandChild() {};
};
Run Code Online (Sandbox Code Playgroud)

所以现在我想按照以下规则排序:

  1. 对于任何Child对象cBaseObject b,b<c
  2. 要比较BaseObject对象id,请像以前一样使用它的s.
  3. 要比较Child对象,请比较它var.如果它们相等,则回退到规则2.
  4. GrandChild对象应该回退到Child行为(规则3).

我最初认为我可能会做一些演员阵容Comparator.但是,这会消除常数.然后我想我可能比较typeids,但是一切看起来都很混乱,甚至都不正确.

我怎么能实现这种,仍在使用list<BaseObject*>::sort

谢谢

小智 12

您正在考虑进行双重调度 - 即根据两个对象的类型而不是一个来调用虚函数.请查看这篇维基百科文章,了解单挑局http://en.wikipedia.org/wiki/Double_dispatch.我必须说,每当我发现自己处于这种情况时,我会尝试改变方向:-)

我可以对您的代码做一些观察.它并没有完全错误,但是:

  • 在C++中,std :: list是最后的容器 - 你应该默认使用std :;向量,除非你特别需要一个只有list提供的功能:

  • 受保护的数据总是一个坏主意

  • @YuppieNetworking受保护的数据使您的派生类变得依赖于基础的实现细节,使更改变得困难.它永远不必要.有关我在列表中进一步查阅的信息,请参阅http://punchlet.wordpress.com/2009/12/27/letter-the-fourth. (3认同)
  • 我选择`std :: list`因为我想快速擦除它中的元素.你能详细说明"受保护的数据是个坏主意"吗? (2认同)