这是对ptr_vector进行排序的正确方法吗?

时间:2012-03-14 07:06:02

标签: c++

我正在尝试使用boost的指针容器,并将STL算法应用于它。我写了一段代码来对ptr_vector<Point>进行排序,其中Point是一个成员int x, y的类。代码如下:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/ptr_container/ptr_list.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

using namespace std;

struct Point {
int x, y;
  Point(int xx, int yy) : x(xx), y(yy) {
   cout << "Point: " << x << " " << y << endl;
  }
 ~Point() {
  cout << "~Point: " << x << " " << y << " this: " << this << endl;
 }
};

struct ComparePoint{
 bool operator() (const Point& p1, const Point& p2) {
  return (p1.x + p1.y < p2.x + p2.y);
 }
};

struct PrintPoint{
 bool operator() (const Point& p) {
  cout << p.x << " " << p.y << endl;
 }
};
int main() {
 boost::ptr_vector<Point> v;
 v.push_back(new Point(1,3));
 v.push_back(new Point(2,0));
 v.push_back(new Point(3,4));
 v.push_back(new Point(4,1));

 //sort(v.begin(), v.end(), ComparePoint());
 for_each(v.begin(), v.end(), PrintPoint());
 return 0;
}

您可能会注意到我对“sort(v.begin(),v.end(),ComparePoint())”进行注释,在这种情况下,输出(cout)看起来很正常,如下所示。

Point: 1 3
Point: 2 0
Point: 3 4
Point: 4 1
1 3
2 0
3 4
4 1
~Point: 1 3 this: 0x1d3f010
~Point: 2 0 this: 0x1d3f050
~Point: 3 4 this: 0x1d3f030
~Point: 4 1 this: 0x1d3f070

但是,当我取消注释“sort(v.begin(),v.end(),ComparePoint())”时,cout输出如下:

Point: 1 3
Point: 2 0
Point: 3 4
Point: 4 1
~Point: 2 0 this: 0x7fff3f723970
~Point: 3 4 this: 0x7fff3f723960
~Point: 3 4 this: 0x7fff3f723970
~Point: 4 1 this: 0x7fff3f723960
~Point: 4 1 this: 0x7fff3f723970
2 0
1 3
4 1
3 4
~Point: 2 0 this: 0x1e45010
~Point: 1 3 this: 0x1e45050
~Point: 4 1 this: 0x1e45030
~Point: 3 4 this: 0x1e45070

根据输出,排序没问题,但是还有5次析构函数调用。那是从哪里来的?更有趣的是,如果我将sort更改为stable_sort,则输出如下:

Point: 1 3
Point: 2 0
Point: 3 4
Point: 4 1
~Point: 2 0 this: 0x7fffcbe85140
~Point: 4 1 this: 0x7fffcbe85140
~Point: 2 0 this: 0x26010c0
~Point: 1 3 this: 0x26010c8
~Point: 1 3 this: 0x26010d0
~Point: 1 3 this: 0x26010d8
2 0
1 3
4 1
3 4
~Point: 2 0 this: 0x2601010
~Point: 1 3 this: 0x2601050
~Point: 4 1 this: 0x2601030
~Point: 3 4 this: 0x2601070

从输出中看来,Point的两个实例从堆栈中释放,其他4个从堆中释放。由于这种奇怪的行为,我害怕在指针容器上使用算法?你知道如何解释这个或者这是对ptr_vector或其他顺序指针容器进行排序的正确方法吗?

3 个答案:

答案 0 :(得分:4)

您似乎正在使用std::sort进行排序,这会交换元素,从而导致调用析构函数。 boost::ptr_containers documentation表示“不幸的是,不可能使用带有标准库中的变异算法的指针容器。但是,最有用的是作为成员函数提供:”。如果您调用ptr_vector.sort()而我怀疑您将看不到对析构函数的调用。

答案 1 :(得分:1)

这与boost::ptr_vector无关。 std::sort通过使用临时值重新分配值来对事物进行排序。正是这些临时工作被摧毁了,毁灭者会打电话给你看。

至于为什么std::stable_sort会破坏一些动态分配的对象......我不知道。

答案 2 :(得分:1)

std::sort通过交换或移动传递给它的迭代器引用的元素来进行操作。

您没有为swap专门设置Point,因此使用了默认的std::swap,这会创建临时对象。你正在看到这些临时工的破坏者。

相关问题