在c ++中的类中包装算法时,我经常遇到const正确性的问题.我觉得我想要一个可变功能,虽然这是不允许的.任何人都可以建议我如何实现如下的类?
以下是我要编写的代码.
但是,如果用户在不调用run()的情况下请求结果,我希望get_result()函数运行算法.这打破了const的正确性,因为我有一个const函数调用非const函数.
class operate_on_data
{
std::vector<double> m_data; // the data to modify
bool m_completed; // check to see if the function run() has been called
public:
operate_on_data(std::vector<double> data)
: m_data(data), m_completed(false) {} //initialise
void run() //I don't want this function to be const
{
//The algorithm goes here - it alters m_data.
m_completed = true; //the algorithm has been run
}
std::vector<double> get_result() const //I want this function to be const
{
/*The following breaks const correctness because
I am calling a non-const function from a const function
- but this feels like the right thing to do ... */
if (!m_completed) run(); //run the algorithm if it has not run already
return m_data; //return
}
};
Run Code Online (Sandbox Code Playgroud)
我曾经设法编译上述类的唯一方法是
我的理解是mutable关键字是为第三个选项设计的,其中实现需要更改数据,但用户合理地期望简单的返回,因此const函数.
但是,我不想做最后一个选项,因为我希望用户能够准确选择何时更改数据.但是,他们有可能忘记调用run(),因此我想强制算法,如果他们在不调用run()的情况下请求结果.我觉得想要使run()变得可变 - 但我不被允许.
写这样一堂课的正确方法是什么?
make run()const,并使m_data和m_completed变为可变.这有效,但在概念上是错误的,因为run()明显改变了数据.
事实并非如此.事实上,你班级中的变量已被改变,但你永远无法证明这一点.调用run()不会更改用户可以从类的接口检索的任何内容.如果您无法检索有关此类更改的任何信息,则无法证明该更改.这不仅是一个语义问题的更多,它直接讲的"可变"关键字的整点.
'mutable'关键字被误解了很多.
这就是说,虽然与最低限度给定的信息我有我可能会做上述方式,我不会推荐它.鉴于对问题的更大看法,几乎可以肯定有一种更好的方法.
我可能使用的另一种方法是你显然避免使用的方法:强制用户在使用get_data()之前调用run().说实话,这也是一个非常不理想的方法.也许更是如此.
编辑:
如果您决定使用可变方法,那么我建议进行一些更改.有一个名为'run()'的函数是const并且没有任何感兴趣的东西会让人感到困惑.这个函数当然应该是非常量的.因此,如果决定以这种方式做这件事,我会做的就是让run()调用一个const和private函数,它具有当前'run()'函数的行为,get_data也引用它( )在规定的条件下.
一些抽象的评论可以帮助你澄清事情:
const 方法是那些不修改对象的概念"状态"的方法,const方法是那些做的.mutable字段是每个对象的字段,但不被视为对象概念的一部分state(就像一些被懒惰和记住的缓存值).问题可能operate_on_data不是一个定义明确的类.什么是类"operate_on_data"的对象?这个对象的"状态"是什么?什么不是?这听起来很尴尬(至少对我而言) - 对某些设计的尴尬描述可能表明反直觉的设计.
我的想法是你在一个奇怪的课堂上保持"操作"和"操作结果"的不同概念,这会导致混乱.
| 归档时间: |
|
| 查看次数: |
13271 次 |
| 最近记录: |