代码之家  ›  专栏  ›  技术社区  ›  alfC

C++11的“const==可变”,非const==无保护==需要时高效?

  •  0
  • alfC  · 技术社区  · 3 年前

    正如我在这个问题中所介绍的那样, C++11's "const==mutable", Provide two classes for efficiency? , 在C++98或线程之前,尽管在某些情况下是不正确的,但使用mutable编写内部隐藏的类是很常见的。

    在C++11中,Herb Sutter说从现在开始 const == thread safe ,这意味着可变字段应该由互斥体保护。

    所以我认为,一些真正知道他/她在做什么的人实际上可以通过在非const的情况下做一些特殊的事情来获得单个类的更通用的版本。

    struct Widget {
    private:
      int getValue_aux() const{
        if (cacheValid) return cachedValue;
        else {
          cachedValue = expensiveQuery(); // write data mem
          cacheValid = true;                    // write data mem
          return cachedValue;
        }
      }
    public:
      int getValue() {
        return get_value_aux();  // no lock
      }                                    
      int getValue() const{
        std::lock_guard<std::mutex> guard{m}; // lock mutex
        get_value_aux();
      }                                      // unlock mutex
    ...
      private:
      mutable std::mutex m;
      mutable int cachedValue;
      mutable bool cacheValid;
    ...
    };
    

    因此,a)普通用户可以使用非const实例 Widget 作记号 它不打算在线程安全上下文中使用,也不需要为互斥锁付费b)真正知道自己在做什么的用户可以 const_cast 或者把它包起来 mutable 如果他知道线程安全在代码的特定点上不会成为问题(但他/她仍在存储互斥体)。

    这是对Widget的合理概括吗?还是有缺陷?


    注:如果你认为 const 和非- const 为了提高效率,应该提供版本,您可能会发现这个问题也很有趣: C++11's "const==mutable", How to implement copy? efficiently?

    0 回复  |  直到 3 年前