C++ 对象接收堆栈溢出异常c+;的排序向量+;

C++ 对象接收堆栈溢出异常c+;的排序向量+;,c++,sorting,vector,stl,std,C++,Sorting,Vector,Stl,Std,我正在尝试按属性对Student对象的向量进行排序: class Student { private: std::string nume; int an; std::list<Curs> cursuri; ... public: Student(); Student(std::string nume, int an); virtual ~Student();

我正在尝试按属性对
Student
对象的向量进行排序:

class Student
{
    private:
        std::string nume;
        int an;
        std::list<Curs> cursuri;
        ...
    public:
        Student();
        Student(std::string nume, int an);
        virtual ~Student();
        ...
};
首先,我尝试了这种方法:

void sortStudenti(std::vector studenti){
结构学生比较
{
布尔运算符()(学生常量和a、学生常量和b)
{
返回a.getMedie()>b.getMedie();
}
};
std::sort(studenti.begin()、studenti.end()、studentCompare());
适用于(汽车专业学生:studenti){
学生:afisare();
}
}
但是我遇到了一些
const
访问错误,所以我尝试了另一种方法

编辑:附加代码


完整的代码在

上可用。您可以通过引用传递向量,而无需通过引用将对象传递到循环中来更改对象,如下所示

但请确保成员函数
afisare
为const

void sortStudenti(std::vector<Student>& studenti) {
    struct studentCompare
    {
        bool operator()(Student const& a, Student const& b)
        {
            return a.getMedie() > b.getMedie();
        }
    };


    std::sort(studenti.begin(), studenti.end(), studentCompare());

    for (const auto& student : studenti) {
        student.afisare();
    }
}
void sortStudenti(std::vector&studenti){
结构学生比较
{
布尔运算符()(学生常量和a、学生常量和b)
{
返回a.getMedie()>b.getMedie();
}
};
std::sort(studenti.begin()、studenti.end()、studentCompare());
用于(const auto&学生:studenti){
学生:afisare();
}
}
但我认为这一例外还有另一个原因。当
sort()
尝试交换
Student
元素时,它会临时复制
Student
元素,您应该检查您的类定义。由于不指定任何其他内容,因此将执行默认的逐个成员复制

在你的
Student
课堂上,你有一个
Curs
的列表。该列表与它包含的
Curs
元素同时复制。但对于Curs,您已经定义了自己的赋值运算符:

Curs& Curs::operator=(Curs arg) noexcept
{
    std::swap(*this, arg);
    return *this;
}
生成的
swap()
后面的代码使您再次复制游标,这将再次调用swap和游标。。。。依此类推,直到堆栈溢出或内存耗尽

顺便说一句,我看到您创建这个操作符是为了绕过Curs类包含的const成员背后的限制。以这种方式欺骗编译器来更改常量元素是未定义的行为。因此,对于需要复制的成员,请去掉常量

只要去掉这个(错误实现的)操作符和常量,它就会工作


补充建议 这个问题确实是一个复杂的问题,只需提取一些代码就可以解决。特别是当问题不在我们认为的地方时。因此,我今后只能向您推荐:

最大限度地利用您的错误信息

  • 在问题中发布完整的错误消息
  • 在堆栈溢出的情况下:浏览堆栈跟踪,直到找到您的一些代码,查看它发生在代码的哪个部分。这有助于缩小研究范围
  • 如果您再多浏览一点,还可以检查是否存在无止境的递归(数据量小的堆栈溢出的最常见原因):非常长的几乎相同的连续调用是一个典型的症状
降低出错风险

  • 在开始构建更复杂的类之前,进行测试以确保底层类按预期工作
  • 即使您没有足够的时间编写广泛的测试,您至少应该尝试每个类成员函数。如果您做的测试只是检查
    Curs::operator=
    是否有效,那么您就可以节省大量额外的实验;-)
@Grandin98您还通过值而不是引用在studenti向量中循环,这意味着您正在对复制的对象调用afisare函数。明白为什么要通过值而不是引用传递向量了吗?关于stack overflow exception可能与您的学生类及其处理复制的方式有关。@EyalD我没有将向量作为引用传递,因为我不想修改原始列表无法复制stackoverflow异常。发布类定义本身此答案与问题中指定的问题无关header@mangusta询问者希望通过引用传递对象,而不更改引用以避免复制!!。请看关于这个问题的评论。做得好,我甚至无法编译该代码(minGW g++)。我删除了操作符重载函数,至少是为了编译。我甚至无法想象这就是原因