[英]std::sort on a vector of Objects containing Objects* pointers
假设我定义了以下结构:
struct dockPose {
Complex* pose;
int Cluster;
struct dockPose* DP;
float Distance;
int Density;
};
typedef struct dockPose DockPose;
然后,我声明一个矢量,它将使用std :: sort()函数按密度值排序。 在调用std :: sort之后,我的DockPose * DP指针是否仍然指向它之前指向的相同DockPose实例? 如果没有,我该怎么做才能确保DP指针指向排序之前指向的相同DockPose(如果有什么我可以做的话)?
是的,指针仍然指向同一个实例。 但这可能不是你真正想要的。 当你在向量上调用std::sort
时,它不会改变实例的位置(这甚至不是你在C ++中可以做的事情)。 它互相交换价值。 用简化的例子可能更好地解释了这一点。 采取这个结构:
struct Foo
{
int x;
Foo* buddy;
};
bool operator<(Foo const& lhs, Foo const& rhs)
{
return lhs.x < rhs.x;
}
现在,让我说我制作一个这样的向量,减少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];
}
现在,如果我对这个向量进行排序,它基本上会逆转。 但实例本身并没有改变它们的位置。 相反,它们的值会发生变化,使得第一个值具有最低的x
值,并且从那里开始增加。 现在,指针成员随x
值一起变化。
因此,例如, vec[0]
, x
值为4,指向vec[1]
( x
值为3)。 排序后,这些值将最终在最后一个元素vec[4]
。 所以vec[4]
的x
值为4,指向vec[1]
的指针(在排序后, x
值为1)。
因此,在排序之前, x
值为4的元素有一个指向x
值为3的元素的指针。排序后, x
值为4的元素有一个指向元素的指针,其x
值为我怀疑这是你想要的。
由于您对实例的身份感兴趣,而不仅仅是它们的值,您可能应该使用类似std::vector<std::unique_ptr<dockPose>>
。 对于我的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();
}
请注意,执行此操作时,需要使用其他比较功能。 比较解除引用的指针而不是指针本身。
std::sort
只会在向量中移动对象,但指针本身仍将指向它们最初指向的相同内存位置。
排序不会更改这些指针的值。 指针只是保存内存地址的变量,排序向量不会更改向量中对象的任何成员变量数据。
如果你有一个DockPose
对象的向量,你将它们视为值,在这种情况下,保持指针是一个坏主意。 我怀疑你实际上希望它们是实体(即使它们具有相同的值,两个实体也是不同的)。
在这种情况下,你应该有一个指向实体的指针向量; 排序指针向量将不会使DP
指针无效。
保持指向向量中的对象不是一个好主意。 如果碰巧导致调整大小,即使是简单的push_back()也可能使所有指针无效。 如果要保留指向容器中对象的指针,最好使用std :: list
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.