C++ Logical Constness场景下函数未返回字符串表示问题排查
问题根因
代码实现逻辑常量性(Logical Constness)的缓存设计思路本身符合参考资料描述,错误出在mutable成员变量未初始化,触发了未定义行为:
cache_valid是标记缓存是否有效的布尔值,构造时没有赋初始值,对象创建后这个变量会读取内存中的随机脏值。第一次调用string_rep()时,如果这个随机值恰好为true,就会跳过缓存计算逻辑,直接返回未初始化的cache内容,自然得不到正确的日期字符串。cache作为存储缓存结果的字符串成员,同样没有做显式初始化,初始状态不符合预期时也会导致返回结果异常。
修复方案
在Date类的构造函数初始化列表中,补充两个mutable成员的初始化:将cache_valid初始值设为false(表示初始状态缓存无效),cache初始化为空字符串即可。
修复后的完整可运行代码:
/* Section 16.2.9.2 The C++ Programing Language Bjarne Stroustrup 4th Edition Book, pages 462-463 */ #include <iostream> #include <string> using std::cout; using std::endl; using std::string; using std::to_string; class Date { private: int d, m,y; mutable bool cache_valid; mutable string cache; void compute_cache_value() const { string dd = to_string(d); string mm = to_string(m); string yy = to_string(y); cache = dd + "," + mm + "," + yy; } public: // 补充cache_valid和cache的初始化 explicit Date(int dd, int mm, int yy):d{dd}, m{mm}, y{yy}, cache_valid{false}, cache{} {}; string string_rep() const; }; string Date::string_rep() const { if (!cache_valid) { compute_cache_value(); cache_valid = true; } return cache; } int main() { Date dx(25,3,2011); string s1 = dx.string_rep(); cout << s1 << endl; // 运行输出:25,3,2011 return 0; }
补充说明:mutable修饰的成员仅代表可以被const成员函数修改,不代表它可以跳过C++变量初始化规则。所有类成员变量无论修饰符是什么,都应当在构造时给出明确初始值,避免未定义行为。
内容的提问来源于stack exchange,提问作者user3602207
相关产品推荐
相关产品推荐

