Странная проблема при итерации набора STL <CStudent>в C ++ - PullRequest
0 голосов
/ 19 октября 2018

У меня есть класс CStudent и класс CStudentGroup, в котором есть один член set<CStudent>.Я заполняю множество объектов из класса CStudentGroup.Я хочу повторить этот набор и распечатать через получатель класса CStudent баллы всех студентов в наборе.Я делаю это, назначая новый набор.Затем я повторяю набор с iterator it.Однако компилятор выдает ошибку *the object has type qualifiers that are not compatible with the member function CStudent::getP; object type is const CStudent* Я хотел бы спросить, как я могу это сделать?Заранее спасибо.

#include <iostream>
#include <string>
#include <set>
using namespace std;
class CStudent {
    string m_strFN;
    int m_iPoints;
public:
    void setP(int p) {
        m_iPoints = p;
    }
    void setFN(string f) {
        m_strFN = f;
    }
    int getP() {
        return m_iPoints;
    }
    string getFN() {
        return m_strFN;
    }
    CStudent() {
        m_strFN = "123456789";
        m_iPoints = 70;
    }
    CStudent(const CStudent& stud) {
        m_strFN = stud.m_strFN;
        m_iPoints = stud.m_iPoints;
    };
    CStudent(int p) {
        m_iPoints = p;
    }
};
class CStudentGroup {
    set<CStudent> m_setStudents;
public:
    CStudentGroup(const CStudentGroup& grp) {
        m_setStudents = grp.m_setStudents;
    };
    CStudentGroup(set<CStudent> st) {
        m_setStudents = st;
    }
    CStudentGroup() {
        CStudent s1(50), s2, s3(s2);
        m_setStudents.insert(s1);
        m_setStudents.insert(s2);
        m_setStudents.insert(s3);

    }
    set<CStudent> gets() {
        return m_setStudents;
    }
};

int main()
{
    CStudentGroup group;
    set<CStudent> stt = group.gets();
    for (set<CStudent>::iterator it = stt.begin(); it != stt.end(); it++) {
        cout << it->getP() << endl;
    }
}

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

std::set сохраняет ключи как постоянное значение, так как изменение ключа может быть причиной изменения его положения в красно-черном дереве (типичная реализация std::set).Другими словами, ваш CStudent объект считается const или неизменяемым.

Здесь можно решить проблему с использованием std::set::const_iterator в качестве типа итератора внутри цикла в сочетании с std::set::cbegin() и std::set::cend()звонки.Другое возможное решение - использовать foreach -loop:

for (CStudent const& student : stt)
    std::cout << student.getP() << '\n'; 

Более того, вам нужно изменить объявление CStudent::getP() на постоянный метод.

0 голосов
/ 19 октября 2018

Объекты внутри std::set всегда const.То есть, чтобы защитить их, в случае, если вы решите изменить какое-либо ключевое поле, порядок сортировки изменится, а установленный инвариант нарушится.

Таким образом, в основном set<CStudent>::iterator - это const_iterator, и вы получите const CStudent& ссылка.Поскольку ваш CStudent::getP не является const функцией-членом, вы не можете использовать ее.

Решение, сделайте его const:

int getP() const {
    return m_iPoints;
}

Естественно, вы хотите пометить как const любая функция, которая не изменяет содержимое вашего объекта, не только те, которые std::set требуют от вас этого.Это иногда называется const-правильность и всегда является хорошей практикой.

...