繁体   English   中英

const_cast 的善意案例?

[英]A benevolent case for const_cast?

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

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

我有一些由控制器拥有的模型对象,通常是非常量的。 我将它传递给不应能够修改模型对象的视图,因此在传递给视图时将对象声明为 const 参数是合乎逻辑的。 然而,视图也使委托回调到控制器,将模型对象作为参数传递(例如,用户单击此对象)。 回调参数也必须是常量。 在回调方法中,控制器想要对模型进行更改,但是模型是const,所以它做不到。

两种解决方案:

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

想法?

有两种处理const

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

  2. 如果这段代码不会改变它们,事情就是const

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

在 (2) 下,这意味着对象不是const 如果间接地,视图可以更改对象。 它可能会导致对象发生更改。 说它是const意味着视图与对象的交互纯粹是“读取状态”,而不是改变状态——但是单击对象的“删除”按钮并使其删除是一个变异操作。

在 (1) 下,您的引用应该是const ,因为您不是自己修改它。 其他人是在他们有权这样做的授权下进行的。

这是一场冲突。 并且 (1) 是一种可以接受的使用const 但是当使用 (1) 时,你应该有一个到对象的替代路径作为非const

我们可以在vector.erase下看到这vector.erase 它(现在)需要const_iterator s。 即使这些迭代器本身不允许修改矢量,非const的岬*this提供了允许修改的替代访问路径。

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

当视图进行委托回调时,它可能传递一个标识符而不是一个对象——或者,控制器可能会以某种方式从对象中提取标识符,并在它自己的对象列表中查找它。

这不是const_cast的好例子。 如果view接受model作为const那么它可以被赋予一个真正的const实例model 然后尝试将该实例传递给控制器​​是不正确的。 如果提供给viewmodel引用可用于修改model ,则它不能是const

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM