如何修改const的私有成员?

时间:2011-06-30 19:18:13

标签: c++ vector const mutable

我知道这听起来像一个奇怪的问题,但请耐心等待。

我有一个自定义类,它有一些大对象需要通过引用返回以避免副本。

我的班级看起来像这样:

    class csv_File {
    public:
      csv_File(std::string); //constructor
      std::string const& access(int,int) const;
      void modify_element(int column,int row ,std::string value) {
        storage.at(row).at(column)=value;
    }

    private:
      mutable std::vector < std::vector<std::string> > storage;

    };

访问代码是:

    string const& csv_File::access(int column,int row) const {
    return storage.at(row).at(column);
    }

当我尝试编译它时,我得到一个错误,因为它想要

csv_File::modify_element(int column,int row ,std::string value) const {}

实际上,存储在逻辑上是常量,但我只需要偶尔修改一次。有没有办法做到这一点?

另外,一个相关的问题。如果我调用modify_element来修改存储中的元素,但之前我已经使用访问返回了对该元素的引用,那么先前返回的引用是否会在modify_element调用之后获取新值?

1 个答案:

答案 0 :(得分:1)

在修复你的程序之后,以及来自@ user763305的提示,我想你有这样的东西(注意:这个程序编译,但在运行时调用未定义的行为,因为storage向量留空) :

#include <string>
#include <vector>

class csv_File {
public:
  csv_File(std::string) {}
  std::string const& access(int,int) const;
  void modify_element(int column,int row ,std::string value) {
    storage.at(row).at(column)=value;
  }

private:
  mutable std::vector < std::vector<std::string> > storage;

};

std::string const& csv_File::access(int column,int row) const {
  return storage.at(row).at(column);
}

const csv_File& Factory() { static csv_File foo("foo.txt"); return foo; }
int main(){
    const csv_File& f(Factory());
    f.modify_element(1, 2, "hello");
}

你得到这样的错误:

cs.cc: In function ‘int main()’:
cs.cc:24: error: passing ‘const csv_File’ as ‘this’ argument of ‘void csv_File::modify_element(int, int, std::string)’ discards qualifiers

所以,你有一个const对象,并试图在其上调用modify_element。从逻辑上讲,这是一个错误 - 您无法修改const个对象!

在我看来,你有两个修复选择。您可以声明vector对象mutablemodify_element方法const,也可以修改对象工厂以返回非const引用。

解决方案1:

...
  void modify_element(int column,int row ,std::string value) const {
    storage.at(row).at(column)=value;
  }
...

解决方案2:

...
const csv_File& Factory() { static csv_File foo("foo.txt"); return foo; }
csv_File& RW_Factory() { static csv_File foo("foo.txt"); return foo; }
...
  const csv_File& f(RW_Factory());
...

<小时/> 的 修改 是的,如果您之前在string中返回了对vector的引用,并且您随后像string那样为modify_element分配了新值,那么之前的参考将反映新值。

请注意,如果您销毁向量,删除vector元素或执行任何操作以使vector增长超出其先前容量,则先前的引用将无效。