课堂设计问题

use*_*983 3 c++ class

在"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;
}
Run Code Online (Sandbox Code Playgroud)

此外,作者还举例说明了以下内容:

Date d1;
const Date d2;
string s1 = d1.string_rep( );
string s2 = d2.string_rep( );
Run Code Online (Sandbox Code Playgroud)

作者表示第四个例子将显示未定义的行为.我想知道为什么.

Mik*_*one 5

string_rep检查是否有日期的缓存字符串表示.如果没有,它调用compute_cache_value方法来创建字符串表示并对其进行缓存,然后将缓存表示标记为有效,以便将来调用string_rep不重新计算它.

该行将const Date d2;显示未定义的行为,因为编译器可能认为它可以放入d2非易失性存储器(例如,微控制器中的闪存,或只读标记的存储器或存储器映射的存储器),并且const_cast<Date*>在这种情况下可能不起作用,导致cache_valid停留false或者cache保持空弦.

PS正如Michael J在下面指出的那样,几乎总有更好的方法来做事而不是使用const_cast.在此示例的情况下,mutable关键字派上用场.简而言之,标记类成员会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;
}
Run Code Online (Sandbox Code Playgroud)

...虽然我认为它是compute_cache_value有责任设置cache_valid,我会考虑加入operator string() const { return string_rep(); }Date.

最后一件事情mutable是,编译器更好地了解发生了什么,并且在类似情况下d2,可以将对象放在易失性存储器中,尽管它声明为const.