指向从未变为常量的常量对象的C++指针

C++ pointer pointing to const object that was never made const

本文关键字:常量 对象 C++ 指针      更新时间:2023-10-16

我有一组Students和一个迭代器,它可以找到一个特定的Students,然后我需要更改它。问题是,当我改变指针指向的对象时,它会说对象是常量。我不知道为什么会这样,因为我认为我从来没有明确地使对象恒定。我对C++还比较陌生,所以我可能会做一些意外的事情来使Student对象常量。

这是的主要功能

set<Student> students;
ifstream file(*somefilename*);
while (!file.is_open())
{
cout << filename << endl;
cout << "Could not open file. Enter new filename: ";
cin >> filename;
file.open(filename);
}
while (!file.eof()) {
string temp = "";
string name;
int regNo;
if (file.eof())break;
for (int i = 0; i < 3; i++) {
if (i == 0)
file >> regNo;
else {
file >> temp;
name += temp;
}
}
cout << "For loop done" << endl;
students.insert(Student(name, regNo));
}
file.close();
file.open("ex1/marks.txt");
while(!file.eof()){
int regNo;
string module;
int mark;
file >> regNo;
Student tempStud("",regNo);
file >> module;
file >> mark;
set<Student>::iterator it = students.find(tempStud);
if (it != students.end()) {
**it->addMark(module, mark);**//here's the problem code
}
}
file.close();
for (set<Student>::iterator it = students.begin(); it != students.end(); it++)
cout << *it << endl;
cin.get();}

这是学生类的头文件

public:
Student(const string &name, int regNo);
int getRegNo() const;
void addMark(string& module, float mark);
float getMark(const string &module) const;
float getMin() const;
float getMax() const;
float getAvg() const;
bool operator <(const Student& s2) const;
bool operator >(const Student& s2);
bool operator ==(const Student& s2);
private:
int regNo;
map<string, float> marks;  // keys are modules, values are marks in range 0.0 to 100.0
friend ostream& operator<<(ostream &str, const Student &s);

您没有意外地使Student对象成为const


问题

这是您的问题:(C++文档)

集合中的所有迭代器都指向常量元素。

换句话说,即使元素在技术上不是constset也不允许通过迭代器修改元素。

那么为什么set是这样定义的呢?(来源)

集合的元素将按排序顺序排列。如果允许修改一个元素,则无法维护此排序顺序。因此,您不能修改项目。


解决方案

你有三种选择之一。

1) 不使用set

除非有一个非常好(非常具体)的理由需要使用set,否则不要使用。请改用map。它不会有同样的限制。

2) 删除并插入

删除旧元素并插入该元素的"更新"版本。这需要O(1)时间。(示例)

3) 使用mutable

如果要修改的数据成员不参与对象类型的自然排序,则将它们声明为mutable。这相当于说它们的值不会改变类的逻辑const实例的身份。这将允许您对const对象或迭代器(例如)中的数据成员进行变异