指向从未被设为 const 的 const 对象的 C++ 指针 [重复]

Posted

技术标签:

【中文标题】指向从未被设为 const 的 const 对象的 C++ 指针 [重复]【英文标题】:C++ pointer pointing to const object that was never made const [duplicate] 【发布时间】:2017-01-03 02:56:24 【问题描述】:

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

这里是主要功能

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();

这是Student类的头文件

    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);

【问题讨论】:

错误发生在哪一行?错误消息到底说了什么? (引用它)另外,请确保发布minimal 示例 它说 what 对象是 const? Relevant question。其中的 MCVE 似乎是修改 std::set 中元素的最佳方式。 Another relevant question,声明可变的。 【参考方案1】:

您没有做任何事情来使学生对象const 意外。


问题

这是你的问题:(C++ documentation)

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

换句话说,set 将不允许您通过迭代器修改元素,即使这些元素在技术上不是 const

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

集合的元素将按排序顺序排列。如果你被允许 修改一个元素,那么这个排序顺序就不能保持了。 因此,您不能修改该项目。


解决方案

您有以下三种选择之一。

1) 不要使用set

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

2) 删除和插入

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

3) 使用mutable

如果要修改的数据成员不涉及对象类型的自然排序,则将它们声明为mutable。这相当于说它们的值不会改变逻辑上const 类实例的标识。即使在 const 对象或迭代器 (example) 中,这也可以让您改变这些数据成员

【讨论】:

为什么不在提交前写一个完整的答案? @AustinBrunkhorst Point #6 here 我特别指的是在部分状态下发布答案。该链接是正确的,但我不认为它指的是您的流式编辑方法,因为您实际上是在输入它们。 我以为是这样的,但我找不到任何可以证实的东西。非常感谢!我最终选择了您建议的第二个选项,并且效果很好。

以上是关于指向从未被设为 const 的 const 对象的 C++ 指针 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C++,成员函数返回对包含指向 const 对象的指针的向量的 const 引用

const关键字

虚函数后面的const=0

C++ const 修饰符

C++ _ const的用法,特别是用在函数前面与后面的区别!

const指针