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

dog*_*ano 2 c++ casting const conventions

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

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

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

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

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

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

有一个更好的方法吗?

有没有公​​认的惯例?

Jos*_*eld 9

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

但是,在你的问题中,你const并没有说实话.它正在抛弃constness并存储非const指针 - 这意味着对象可能很好地被修改.你欺骗了用户!构造函数本身对该对象没有任何作用并不重要.它允许其他成员函数修改它.这是不好的行为.你的构造函数不应该const参考.

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

†见6502的评论