在C++中迭代 STL 集时出现奇怪的问题<CStudent>

Strange issue when iterating a STL set<CStudent> in C++

本文关键字:问题 lt gt CStudent 迭代 C++ STL      更新时间:2023-10-16

我有类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;
}
}
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()

std::set内的对象始终const。这是为了保护它们,以防您决定更改任何键字段,排序顺序更改并且设置不变性被破坏。

所以基本上set<CStudent>::iterator是一个const_iterator,你会得到一个const CStudent&参考。由于CStudent::getP不是const成员函数,因此无法使用它。

解决方案,使其const

int getP() const {
return m_iPoints;
}

当然,您希望将任何不更改对象内容的函数标记为const,而不仅仅是std::set要求您这样做的函数。这有时被称为恒量正确性,并且始终是一种很好的做法。