繁体   English   中英

良好做法:不变为非恒定演员

[英]Good practice: Constant to non-constant cast

当一个函数不修改一个对象参数时,我总是让它要求一个常量引用,即使引用的对象不是真正的常量。 这是错的吗?

对于包装类,我想写这个:

template<class B>
class Wrapper{
private:
  B* base_;
public:
  Wrapper(const B& b) { base_ = const_cast<B*>(&b); }
  void ModifyBase();
};

构造函数不会修改基数,因此它要求提供常量引用。

包装器有一些方法需要修改基类,因此它需要存储一个非常量指针(因此转换)。

我觉得我的解决方案不是最好的。

有一个更好的方法吗?

有没有公​​认的惯例?

当您选择参数作为const引用时,您告诉用户“您可以相信,如果您传递给我一个对象,它将不会被[通过此引用]†修改。” 您应该尽可能经常这样做,因为用户可以通过查看类型了解更多关于您的功能将会做什么和不会做什么。 此外,传递可变引用可能会导致代码难以推理。

但是,在你的问题中,你的const并没有说实话。 这是虚掷的const内斯和存储非const指针-这意味着该对象很可能得到修改。 你欺骗了用户! 构造函数本身对该对象没有任何作用并不重要。 它允许其他成员函数修改它。 这是不好的行为。 您的构造函数不应该使用const引用。

不仅如此,但您当前的实现允许未定义的行为。 即使最初声明为const的对象被赋予Wrapper ,它也不关心。 它抛弃了它的const并允许其他成员函数修改它。 修改最初为const的对象是未定义的行为。

†见6502的评论

它并不真正重要的是, ctor不会改变的对象ctor ,会发生什么情况后, ctor完成就是为什么你需要一个非const对象指针B 所以它与传入的B对象的所有权和生命周期有关:如果你想获得所有权(通过& reference,那么对象必须是非const因为它可以被改变。如果你想简单地复制B传入的对象,然后不使用引用,按值传递并存储指向副本的指针。

暂无
暂无

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

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