我正在尝试使用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或其他顺序指针容器进行排序的正确方法吗?
答案 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
,这会创建临时对象。你正在看到这些临时工的破坏者。