繁体   English   中英

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

[英]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.

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