Tho*_*ews 3 c++ const-correctness lazy-evaluation
在RAII中,资源在访问之前不会初始化.但是,许多访问方法被声明为常量.我需要调用mutable(非const)函数来初始化数据成员.
示例:从数据库加载
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;
}
Run Code Online (Sandbox Code Playgroud)
我的原始解决方案是将数据成员声明为mutable.我宁愿不这样做,因为它表明其他方法可以改变成员.
如何转换load_from_database()语句以摆脱编译器错误?
Mat*_* M. 20
这不是RAII.在RAII中,您将在构造函数中初始化它,这将解决您的问题.
所以,你在这里使用的是Lazy.无论是懒惰的初始化还是懒惰的计算.
如果你不使用mutable,那么你就是一个受伤的世界.
当然你可以使用a const_cast,但如果有人这样做了:
static const MyClass Examplar;
Run Code Online (Sandbox Code Playgroud)
编译器决定它是只读内存的一个很好的候选者?那么,在这种情况下,效果const_cast是不确定的.充其量,没有任何反应.
如果你仍然希望继续这const_cast条路线,那就R Samuel Klatchko去做吧.
如果你考虑并认为可能有更好的选择,你可以决定包装你的变量.如果是在它自己的阶级,只有3种方法:get,set和load_from_database,那么你就不会担心被mutable.
正如Matthieu已经指出的那样,你在这里尝试做的事与RAII几乎没有关系(如果有的话).同样,我怀疑任何组合const和mutable真正会有所帮助.const并mutable修改类型,并同样适用于对该类型对象的所有访问.
您似乎想要的是少量代码具有写访问权限,而其他任何内容只能读取对该值的访问权限.鉴于C++(和大多数类似语言)的基本设计,正确的方法是将变量移动到自己的类中,少量代码需要写访问作为(或可能是朋友的一部分)的一部分. )那个班.世界其他地方通过类的接口(即,检索值的成员函数)获得只读访问权限.
MyClass你发布的(可能是剥离的)非常接近 - 你只需要自己使用它,而不是作为一个有很多其他成员的大班级的一部分.要改变的主要事情是1)名称从MyClass类似的东西lazy_int,2)(至少根据我的喜好)get_value()应该重命名为operator int().是的,m_value可能需要是可变的,但这不允许其他代码写入值,因为其他代码根本无法访问值本身.
然后,您将该类型的对象嵌入到更大的类中.该外部类中的代码可以将其视为一个int(在只读的基础上),这要归功于它operator int(),但不能写它,只是因为类没有给出任何方法.