c++ - RAII : Initializing data member in const method

标签 c++ lazy-evaluation const-correctness

RAII 中,资源在被访问之前不会被初始化。但是,许多访问方法都声明为常量。我需要调用一个 mutable(非常量)函数来初始化一个数据成员。

示例:从数据库加载

struct MyClass
{
  int get_value(void) const;

  private:
     void  load_from_database(void); // Loads the data member from database.

     int m_value;
};

int
MyClass ::
get_value(void) const
{
  static bool value_initialized(false);
  if (!value_initialized)
  {
    // The compiler complains about this call because
    // the method is non-const and called from a const
    // method.
    load_from_database();
  }
  return m_value;
}

我的原始解决方案是将数据成员声明为mutable。我宁愿不这样做,因为它表明其他方法可以更改成员。

我将如何转换 load_from_database() 语句来消除编译器错误?

最佳答案

这不是 RAII。在 RAII 中,您将在构造函数中对其进行初始化,这将解决您的问题。

所以,您在这里使用的是 Lazy。无论是惰性初始化还是惰性计算。

如果您不使用 mutable,您将陷入一个痛苦的世界。

当然你可以使用 const_cast,但是如果有人这样做了怎么办:

static const MyClass Examplar;

然后编译器决定它是只读内存的一个很好的候选者?那么,在这种情况下,const_cast 的效果是未定义的。充其量,什么也不会发生。

如果您仍然希望采用 const_cast 路线,请像 R Samuel Klatchko 那样做。

如果您仔细考虑并认为可能有更好的选择,您可以决定包装您的变量。如果它属于自己的类,只有 3 个方法:getsetload_from_database,那么您就不会担心它是 可变

关于c++ - RAII : Initializing data member in const method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2478928/

相关文章:

Haskell - 为什么我要使用无限数据结构?

clojure - 使用懒惰的字符串集合在 clojure 中进行分区

c++ - 为什么 stream::good 是错误的示例?

c++ - 有人可以用 C++ 检查我的定时器程序吗

c++ - 在 MFC 中捕获消息 - 有什么区别?

c++ - 从 "const std::string"初始化 "std::istringstream"

C++ 只允许一个成员变量被设置一次

c++ - 为什么在同一个 cpp 文件中包含 header 和前向声明包含的类?

c - 相同的功能不同的结果

C++ 避免 const 和非常量访问的代码重复