我知道这听起来像一个奇怪的问题,但请耐心等待。
我有一个自定义类,它有一些大对象需要通过引用返回以避免副本。
我的班级看起来像这样:
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调用之后获取新值?
答案 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
对象mutable
和modify_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
增长超出其先前容量,则先前的引用将无效。