简体   繁体   English

std :: sort包含Objects *指针的对象向量

[英]std::sort on a vector of Objects containing Objects* pointers

Let's say I define the following struct: 假设我定义了以下结构:

struct dockPose {
    Complex* pose;
    int Cluster;
    struct dockPose* DP;
    float Distance;
    int Density;
};
typedef struct dockPose DockPose;

Then, I declare a vector which will be sorted by Density value using the std::sort() function. 然后,我声明一个矢量,它将使用std :: sort()函数按密度值排序。 After the call to std::sort, will my DockPose* DP pointers still point to the same DockPose instance it was pointing before? 在调用std :: sort之后,我的DockPose * DP指针是否仍然指向它之前指向的相同DockPose实例? If not, what can I do to be sure DP pointers points to the same DockPose it was pointing to before sorting (if there is anything I can do) ? 如果没有,我该怎么做才能确保DP指针指向排序之前指向的相同DockPose(如果有什么我可以做的话)?

Yes, the pointers will still point to the same instance. 是的,指针仍然指向同一个实例。 But that may not be what you actually want. 但这可能不是你真正想要的。 When you call std::sort on a vector, it does not change the location of instances (that's not even a thing you can do in C++). 当你在向量上调用std::sort时,它不会改变实例的位置(这甚至不是你在C ++中可以做的事情)。 It swaps their values with each other. 它互相交换价值。 This is probably better explained with a simplified example. 用简化的例子可能更好地解释了这一点。 Take this struct: 采取这个结构:

struct Foo
{
    int x;
    Foo* buddy;
};

bool operator<(Foo const& lhs, Foo const& rhs)
{
    return lhs.x < rhs.x;
}

Now, lets say I make a vector of these, with decreasing x values, and each one having a pointer to the one that comes after it (and the last having a pointer to the first): 现在,让我说我制作一个这样的向量,减少x值,每个都有一个指向它后面的指针(最后一个指针指向第一个):

std::vector<Foo> vec(5);
for (int i = 0; i < 5; ++i)
{
    vec[i].x = 4 - i;
    vec[i].buddy = &vec[(i + 1) % 5];
}

Now, if I sort this vector, it is essentially going to reverse. 现在,如果我对这个向量进行排序,它基本上会逆转。 But the instances themselves don't change their location. 但实例本身并没有改变它们的位置。 Instead, their values change such that the first one has the lowest x value, and it increases from there. 相反,它们的值会发生变化,使得第一个值具有最低的x值,并且从那里开始增加。 Now, the pointer member changes along with the x value. 现在,指针成员随x值一起变化。

So take, for example, vec[0] , which had an x value of 4, and a pointer to vec[1] (which has an x value of 3). 因此,例如, vec[0]x值为4,指向vec[1]x值为3)。 After the sort, those values will end up in the last element, vec[4] . 排序后,这些值将最终在最后一个元素vec[4] So vec[4] will have an x value of 4, and a pointer to vec[1] (which, after the sort, has an x value of 1). 所以vec[4]x值为4,指向vec[1]的指针(在排序后, x值为1)。

So, before the sort, the element with the x value 4, had a pointer to the element with an x value of 3. After the sort, the element with the x value of 4 has a pointer to the element with the x value of 1. I doubt this is what you wanted. 因此,在排序之前, x值为4的元素有一个指向x值为3的元素的指针。排序后, x值为4的元素有一个指向元素的指针,其x值为我怀疑这是你想要的。

Since you are interested in the identity of the instances, not just their values, you should probably be using something like std::vector<std::unique_ptr<dockPose>> . 由于您对实例的身份感兴趣,而不仅仅是它们的值,您可能应该使用类似std::vector<std::unique_ptr<dockPose>> For my Foo example, I could do something like this: 对于我的Foo示例,我可以这样做:

std::vector<std::unique_ptr<Foo>> vec;
for (int i = 0; i < 5; ++i)
    vec.emplace_back(new Foo);
for (int i = 0; i < 5; ++i)
{
    vec[i]->x = 4 - i;
    vec[i]->buddy = vec[(i + 1) % 5].get();
}

Note that when you do this, you need to use a different comparison function. 请注意,执行此操作时,需要使用其他比较功能。 One which compares the dereferenced pointers, rather than the pointers themselves. 比较解除引用的指针而不是指针本身。

std::sort只会在向量中移动对象,但指针本身仍将指向它们最初指向的相同内存位置。

Sorting will not change the values of those pointers. 排序不会更改这些指针的值。 Pointers are simply variables holding memory addresses, sorting a vector will not change any of the member variable data of the objects in the vector. 指针只是保存内存地址的变量,排序向量不会更改向量中对象的任何成员变量数据。

If you have a vector of DockPose objects you are treating them as values, in which case it's a bad idea to keep pointers to them. 如果你有一个DockPose对象的向量,你将它们视为值,在这种情况下,保持指针是一个坏主意。 I suspect you actually want them to be entities (two entities are distinct even if they have identical values). 我怀疑你实际上希望它们是实体(即使它们具有相同的值,两个实体也是不同的)。

In which case you should instead have a vector of pointers to the entities; 在这种情况下,你应该有一个指向实体的指针向量; sorting the vector of pointers will then not invalidate your DP pointers. 排序指针向量将不会使DP指针无效。

keeping pointers to objects in a vector is not a good idea. 保持指向向量中的对象不是一个好主意。 Even a simple push_back() could make all of your pointers invalid, if you happen to cause a resize. 如果碰巧导致调整大小,即使是简单的push_back()也可能使所有指针无效。 If you want to keep pointers to objects in a container you would be better to use a std::list 如果要保留指向容器中对象的指针,最好使用std :: list

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM