简体   繁体   English

将 std::sort 与自定义 class 一起使用

[英]Using std::sort with custom class

I have created a minimum reproducible example below:我在下面创建了一个最小的可重现示例:

Polygon3D.h:多边形3D.h:

#pragma once
class Polygon3D
{
public:
    // Constructors
    Polygon3D();
    Polygon3D(const Polygon3D& p);
    // Accessors
    void SetAverageZ(float average);
    float GetAverageZ() const;
    // Operators
    Polygon3D& operator= (const Polygon3D& rhs);
    const bool operator< (const Polygon3D& rhs) const;
private:
    float _averageZ;
};

Polygon3D.cpp file: Polygon3D.cpp 文件:

#include "Polygon3D.h"
// Default constructor
Polygon3D::Polygon3D()
{
    _averageZ = 0;
}
// Copy constructor
Polygon3D::Polygon3D(const Polygon3D& p)
{
    _averageZ = p.GetAverageZ();
}
// Accessors
void Polygon3D::SetAverageZ(float average)
{
    _averageZ = average;
}
float Polygon3D::GetAverageZ() const
{
    return _averageZ;
}
// Operators
Polygon3D& Polygon3D::operator=(const Polygon3D& rhs)
{
    return *this;
}
// Used by std::sort to order lists of this class
const bool Polygon3D::operator<(const Polygon3D& rhs) const
{
    return _averageZ < rhs.GetAverageZ();
}

Sort.cpp file:排序.cpp 文件:

#include <iostream>
#include <vector>
#include <algorithm>
#include "Polygon3D.h"

int main()
{
    std::vector<Polygon3D> list;

    Polygon3D temp1 = Polygon3D();
    temp1.SetAverageZ(2);
    list.push_back(temp1);

    Polygon3D temp2 = Polygon3D();
    temp2.SetAverageZ(0);
    list.push_back(temp2);

    Polygon3D temp3 = Polygon3D();
    temp3.SetAverageZ(6);
    list.push_back(temp3);

    Polygon3D temp4 = Polygon3D();
    temp4.SetAverageZ(5);
    list.push_back(temp4);

    std::sort(list.begin(), list.end(), std::less<Polygon3D>());

    std::cout << "Sorted vector: ";

    for (Polygon3D poly : list) 
    {
        std::cout << poly.GetAverageZ();
    }
}

And this is the output I receive:这是我收到的 output:

Sorted vector: 2065

As you can see, the vector is not being sorted and is output in the order the items are added.如您所见,向量未排序,按添加项目的顺序为 output。 Is there a reason why this is not being sorted correctly?是否有原因导致未正确排序? Any help is greatly appreciated.任何帮助是极大的赞赏。

You have defined a copy assignment operator which doesn't actually copy assign the _averageZ member.您已经定义了一个复制分配运算符,它实际上并不复制分配_averageZ成员。 std::sort will be using that to exchange elements of the vector, but because it doesn't actually change any members, the sorting of the _averageZ members in the vector will be unchanged. std::sort将使用它来交换向量的元素,但因为它实际上并没有改变任何成员,所以向量中_averageZ成员的排序将保持不变。

You need to always implement the special member functions properly when you declare them.声明特殊成员函数时,您需要始终正确地实现它们。

The compiler does however define a copy assignment operator that does the correct thing for you implicitly as long as certain conditions are met .但是,编译器确实定义了一个复制赋值运算符, 只要满足某些条件,它就会隐式地为您做正确的事情。

Just remove your user-provided copy assignment overload and copy constructor definitions and declarations from the class and it will work as expected, ie remove Polygon3D(const Polygon3D& p);只需从 class 中删除用户提供的复制赋值重载和复制构造函数定义和声明,它就会按预期工作,即删除Polygon3D(const Polygon3D& p); and Polygon3D& operator= (const Polygon3D& rhs);Polygon3D& operator= (const Polygon3D& rhs); and their implementations.及其实现。 Then the compiler will define a correctly working copy constructor and copy-assignment constructor for you implicitly.然后编译器将为您隐式定义一个正确工作的复制构造函数和复制赋值构造函数。

But if you must have these special member functions declared, then you need to actually copy the _averageZ member in the copy assignment overload.但是如果你必须声明这些特殊的成员函数,那么你需要在复制赋值重载中实际复制_averageZ成员。

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

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