实现std :: list项读/写事件

时间:2009-09-09 04:15:37

标签: c++ list overloading

我是c ++的新手,但我已经开始考虑一个特定的任务,这个任务需要我在每次尝试更改或读取任何列表项时都能添加一个特定的代码块。

结果列表应该尽可能地表现并且看起来尽可能多地使用std :: list,除了这个小的异常,这使我能够在读取/写入该列表时执行特定的任务。

从我到目前为止所发现的,我所能想到的是从list :: iterator派生一个类并重载它的operator *和operator =来实现这些特定的任务。

然后我应该从std :: list派生一个类,并通过重载begin()和end()方法使它使用我的新迭代器类型。或者有更好的方法使它使用自定义迭代器吗?

这将处理迭代器访问,但我可以看到列表甚至可以返回指向它的成员的指针。我想我无能为力,并且必须从我的新列表类中删除此功能。

我很感激你对这个问题的看法。

4 个答案:

答案 0 :(得分:5)

从std :: list派生几乎肯定不是答案。 stl中的集合根本不是从中派生出来的,这样做会导致您遇到问题。

为什么是析构函数问题的典型例子。 stl集合中的析构函数不是虚拟的。如果通过对std :: list的引用删除对象,这将破坏您在派生类析构函数中放置的任何逻辑。例如

std::list* pList = new YourNewListClass();
delet pList; // runs std::list::~list()

您还需要覆盖迭代器上的方法。它需要改变每个可能改变集合的方法。

更稳定的方法是实现自己的std :: list样式类,该类遵循标准的stl容器行为。然后,您可以在您想要事件的地方使用此列表,而不会遇到从std :: list派生的问题。

答案 1 :(得分:1)

查看std::deque将其功能实现为另一个标准集合的适配器的方式。这是要走的路 - 使用组合而不是继承并包装底层集合以提供新的设施。对于奖励积分模板您在底层集合上的实现。对于许多用途,std::vector将胜过std::list,并且您的添加应该能够与用户选择的其中任何一个一致。

答案 2 :(得分:1)

首先要做的事情是......从STL容器中派生一个类,因为它们不是派生的。对于初学者来说,他们的析构函数不是虚拟的。

最简单的方法是在你自己的类中包含一个std :: list并提供类似接口的列表。在这些类似列表的接口中,您可以提供要在/更新列表之前执行的任何其他任务。

另外,请看一下这种设计模式:Decorator

答案 3 :(得分:1)

看看boost::transform_iterator<>。它似乎接近你正在寻找的东西。只要调用transform_iterator<>的运算符*()函数,它就会调用仿函数。预期用途是转换迭代器指向的对象,但没有任何内容表示仿函数不能执行其他操作,只是返回指向对象的原始值。

即使它不是你想要的,它也可能提供你如何解决问题的想法。