const_cast的慈善案例?

问题描述

我已经阅读了很多讨论,认为C ++中的const_cast被认为是错误和危险的,除与C代码向后兼容外,不应将其用于其他任何用途。我大体上同意。

但是最近我遇到了以下用例,这让我感到奇怪。

我有一个控制器拥有的模型对象,通常是非常量的。我将其传递给不应修改模型对象的视图,因此在传递给视图时将对象声明为const参数是合乎逻辑的。但是,该视图还会向控制器进行委托回调,将模型对象作为参数传递给用户(例如,用户单击了该对象)。回调参数也必须是const。在回调方法中,控制器想对模型进行更改,但是模型是const的,因此无法执行。

两种解决方案:

  1. 在控制器的回调方法中使用const_cast,因为它知道模型对象是非常量的-但它闻起来。
  2. 传递给视图时不要将模型声明为const参数-但是我不能使用像const声明这样有用的工具,在这种情况下,这似乎非常有用。

有想法吗?

解决方法

有两种处理const的方法。

  1. 如果此代码不会直接更改它们,则为const

  2. 如果此代码不会更改,则为const

在这种情况下,视图不会直接更改对象。但是您希望它间接更改对象。

在(2)下,这表示对象不是const。视图可以间接更改对象。这可能导致对象被更改。说为const意味着与对象的视图交互纯粹是“读取状态”,而不是更改状态-但是单击对象的“删除”按钮并将其删除是一种变异操作。 / p>

在(1)下,您的引用应为const,因为您自己没有修改它。别人是在他们这样做的权利所授予的权力下。

这是一个冲突。并且(1)是使用const的可接受方式。但是,在使用(1)时,您应该以const以外的其他方式替代路线

我们可以在vector.erase下看到它。 (现在)需要const_iterator秒。即使不允许这些迭代器自己修改向量,但const的非*this性质提供了允许修改的替代访问路径。

在您的情况下,控制器拥有该对象,因此应具有对该对象的非const访问路径。这就是您要对对象进行非const修改的路径。

当视图进行委托回调时,它可能传递标识符而不是对象-或控制器可能以某种方式从该对象提取标识符,并将其备份到自己的对象列表中。

,

这不是const_cast的好情况。如果viewmodel接受为const,然后可以为其提供const的真实model实例。然后尝试将该实例传递给控制器​​将是不正确的。如果提供给model的对view的引用可以用来修改model,那么它一定不能是const