c – 如何处理可能指向内部数据的参考论据?
不止一次,我已经跟踪了一个相当令人困惑的错误,只是发现它是由于const参考参数通过方法改变零件方式.这一直是接收参考参数的方法的结果,该引用参数恰好是引用它自己的数据成员之一的一部分.所以当该方法使该成员变异时,引用(尽管是const)也被突变.
一个简单的例子,我在说什么: #include <algorithm> #include <iostream> #include <string> #include <vector> class RecentStringBuffer { public: const std::string & at(size_t index) { return v.at(index); } void add(const std::string & s) { // Remove any previous occurances v.erase(std::remove(v.begin(),v.end(),s),v.end()); // Prepend the new entry v.insert(v.begin(),s); // Truncate older entries v.resize(std::min<size_t>(v.size(),maxEntries)); } private: const int maxEntries = 10; std::vector<std::string> v; }; int main() { RecentStringBuffer r; r.add("A"); // r == [A] r.add("B"); // r == [B,A] r.add("C"); // r == [C,B,A] r.add(r.at(1)); // r == [B,C,A] one would assume? std::cout << r.at(0) << r.at(1) << r.at(2); // Prints "A C A" } 在这个例子中,我们得到了一个令人惊讶的结果,但是如果v已经重新分配了,那么这个引用将被留在v的内存之外,这会更糟.在技??术上,参考无论如何都是无效的,所以发生的是未定义的行为. 类似的情况显然会发生在全局变量而不是数据成员和指针而不是引用,但成员和引用通常会更安全,所以这似乎是一个更令人惊讶的陷阱. 现在,我不是问为什么会发生这种情况(我了解发生了什么)或如何解决(有几个明显的方法).我的问题与最佳做法有关: >这个问题有没有名字? 解决方法
通常,函数的默认合同是它应该做它应该做的事情,即使引用参数是指函数可能修改的东西.
如果一个功能不支持这一点,那么它应该是清楚的. 标准库的一个例子是: > std :: vector :: insert(const_iterator pos,InputIt first,InputIt last)被具体记录为说“如果第一个和最后一个是迭代器到* this的行为是未定义的”. 所以,在你的代码中,你需要修改add()来工作,即使s是指v的成员;或记录它不会工作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |