在《The C++ programming language》一书中,作者给出了如下例子。他提到“需要先填充缓存才能使用”。在我看来,这就是放置compute_cache_value这个函数的原因。但我不明白 string_rep( ) 的功能根据其实现做了什么。感谢您的澄清。
class Date{
bool cache_valid;
string cache;
void compute_cache_value( ); //fill cache
// ...
public:
// ...
string string_rep( ) const;
};
string Date:: string_rep( ) const
{
if (cache_valid == false) {
Date* th = const_cast<Date*> (this); // cast away const
th->compute_cache_value( );
th->cache_valid = true;
}
return cache;
}
另外,作者给出了以下示例:
Date d1;
const Date d2;
string s1 = d1.string_rep( );
string s2 = d2.string_rep( );
并且作者声明第四个示例将显示未定义的行为。我想知道为什么。
最佳答案
string_rep
检查是否有日期的缓存字符串表示形式。如果不是,它调用 compute_cache_value
方法来创建字符串表示并缓存它,然后将缓存表示标记为有效以便将来调用 string_rep
不要重新计算它。
行const Date d2;
将显示未定义的行为,因为编译器可能假设它可以放置 d2
在非 volatile 存储器中(例如微 Controller 中的闪存,或只读标记存储器或存储器映射存储器),以及 const_cast<Date*>
在这种情况下可能不起作用,导致 cache_valid
入住false
或 cache
保持为空字符串。
附言正如下面的 Michael J 指出的那样,几乎总有比使用 const_cast
更好的方法来做事。 .在这个例子中,mutable
关键字派上用场。简而言之,标记一个类(class)成员mutable
告诉编译器即使对象是 const
也可以更改成员。 .
class Date
{
mutable bool cache_valid;
mutable string cache;
void compute_cache_value() const;
// ...
public:
// ...
string string_rep() const;
};
string Date::string_rep() const
{
if (cache_valid == false) {
compute_cache_value();
cache_valid = true;
}
return cache;
}
...虽然我认为它是 compute_cache_value
责任设置cache_valid
, 我会考虑添加 operator string() const { return string_rep(); }
至 Date
.
关于 mutable
的最后一件事是编译器对正在发生的事情有更好的了解,在像d2
这样的情况下, 可以将对象放入 volatile 内存中,尽管它声明为 const
.
关于c++ - 类设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5332419/