c++ - 将 std::sort 与自定义类一起使用
问题描述
我在下面创建了一个最小的可重现示例:
多边形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 文件:
#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();
}
排序.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();
}
}
这是我收到的输出:
Sorted vector: 2065
如您所见,向量没有被排序,而是按照添加项目的顺序输出。是否有原因导致未正确排序?任何帮助是极大的赞赏。
解决方案
您已经定义了一个复制分配运算符,它实际上并不复制分配_averageZ
成员。std::sort
将使用它来交换向量的元素,但因为它实际上并没有改变任何成员,所以_averageZ
向量中成员的排序将保持不变。
声明特殊成员函数时,您需要始终正确地实现它们。
但是,编译器确实定义了一个复制赋值运算符,只要满足某些条件,它就会隐式地为您做正确的事情。
只需从类中删除用户提供的复制赋值重载和复制构造函数定义和声明,它就会按预期工作,即删除Polygon3D(const Polygon3D& p);
和Polygon3D& operator= (const Polygon3D& rhs);
及其实现。然后编译器将为您隐式定义一个正确工作的复制构造函数和复制赋值构造函数。
但是如果你必须声明这些特殊的成员函数,那么你需要_averageZ
在复制赋值重载中实际复制成员。
推荐阅读
- linq - 什么是 F# 的 Seq.cache 的 LINQ to Objects 等效项?
- ios - MetricKit MXDiagnostic 符号化
- python - 旧值不在 SQLAlchemy 中可变 numpy 数组的历史记录中
- java - 我有一个无法启动活动的 java lang
- pine-script - 如何从加载在不同面板中的脚本在主图表上绘制形状?
- javascript - 调用 node-fs-extra 函数 copySync() 期间出现无效回调错误
- html - 角度重新定义路线返回
- javascript - 如何在 React JS 上添加输入数字的增量
- typescript - 将多个文件中的夹具和测试导入 main.js 文件时,TestCafe“未定义夹具”错误
- c# - C# 使用字符串命名类的实例