用于对链表进行排序的继承,而不会造成混乱
Inheritance for sorting a Linked List without clutter
我有一个看起来很简单的问题,但我找不到一个优雅的解决方案。
我正在使用一个链表,我需要对它进行两次排序:
- 一次将一个参数添加为列表元素,并且
- 经过一些处理后,一次在不同的参数上。
我存储在列表中的对象继承自抽象列表项基类。
问题在于重新使用第二个参数。我不想在列表项基类中为其编写纯虚拟访问器,因为我稍后在列表中存储了一些其他对象,这些对象也继承自列表项基类,但第二个访问器对它们没有意义。
我缺少一个干净的解决方案吗?
使用谓词:
std::list<Base*> myList; /* populate */
myList.sort([](Base * const p1, Base * const p2) -> bool
{ return static_cast<Derived*>(p1)->compare_with(*p2); }
);
这假设在排序运行期间,所有元素实际上是指向Derived
的指针,这些具有返回布尔值的成员函数foo
(甚至不需要是虚拟的)。
当然,您可以以任何您喜欢的方式调整谓词的细节。如果您使用的是旧编译器,您还可以将 lambda 表达式替换为传统的拼写谓词类。
如果你不能确定你的所有元素实际上都是Derived
类型,那么你可以用dynamic_cast
来代替,但你必须想办法对所有无与伦比的对象进行排序。在这种情况下,最好先将范围划分为Derived
和不,并且仅对前者进行排序。
理解正确,你有这样的东西:
class Base {
public:
int getParam1() const { ... };
virtual void foo() =0; // this is an abstract class
virtual ~Base() { ... }
}
class Derived : public Base {
public:
int getParam1() const { ... }
int getParam2() const { ... }
}
你在某个地方有一个std::list<Base*> myList
。第一次要对列表进行排序时,执行以下操作:
sort(list.begin(),list.end(),[](const Base*v1,const Base*v2) {
return v1->getParam1()<v2->getParam1();
});
对于第二种类型,您需要使用特定于类Derived
的东西。您不想将纯虚拟访问器getParam2()
添加到Base
中并在Derived
中实现它。但是,如果您知道您的列表仅包含派生对象,则可以毫无问题地使用强制转换:
sort(list.begin(),list.end(),[](const Base*b1,const Base*b2) {
const Derived * d1 = dynamic_cast<const Derived*>(b1);
const Derived * d2 = dynamic_cast<const Derived*>(b2);
return d1->getParam2() < d2->getParam2();
});
请注意,如果列表中的对象不是Derived
,dynamic_cast将返回nullptr
以便您可以安全地检查它。
我是否正确理解您想对某个容器(您自己的设计)的元素进行排序,以便对这些元素进行比较的不同版本?如果是这样,只需为您的排序算法提供比较函子/函数。
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 如何克服提升精神AST混乱
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 关于构造商的呼叫和继承顺序的混乱
- 在继承范围时混乱
- 继承的合法性混乱
- 用于对链表进行排序的继承,而不会造成混乱
- 虚函数, ->运算符, 继承如此混乱