简体   繁体   English

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

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

When a function doesn't modify an object argument, I always make it ask for a constant reference even if the referenced object isn't really constant. 当一个函数不修改一个对象参数时,我总是让它要求一个常量引用,即使引用的对象不是真正的常量。 Is this wrong? 这是错的吗?

For a wrapper class, I'd like to write this: 对于包装类,我想写这个:

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

The constructor doesn't modify the base so it asks for a constant reference. 构造函数不会修改基数,因此它要求提供常量引用。

The wrapper have some methods who will need to modify the base so it needs to store a non-constant pointer (thus the conversion). 包装器有一些方法需要修改基类,因此它需要存储一个非常量指针(因此转换)。

I feel my solution is not the best. 我觉得我的解决方案不是最好的。

Is there a better way to do this? 有一个更好的方法吗?

Is there any accepted convention? 有没有公​​认的惯例?

When you choose your parameter to be a const reference, you're telling the user "You can trust that if you pass me an object, it will not get modified [through this reference]†." 当您选择参数作为const引用时,您告诉用户“您可以相信,如果您传递给我一个对象,它将不会被[通过此引用]†修改。” You should do that as often as possible, because the user can understand more about what your function will and won't do just from looking at the types. 您应该尽可能经常这样做,因为用户可以通过查看类型了解更多关于您的功能将会做什么和不会做什么。 Also, passing around mutable references can lead to code that is difficult to reason about. 此外,传递可变引用可能会导致代码难以推理。

However, in your question, your const is not telling the truth. 但是,在你的问题中,你的const并没有说实话。 It is casting away the const ness and storing a non- const pointer - this means the object may very well get modified. 这是虚掷的const内斯和存储非const指针-这意味着该对象很可能得到修改。 You lied to the user! 你欺骗了用户! It doesn't matter that the constructor itself does nothing to do the object. 构造函数本身对该对象没有任何作用并不重要。 It allows it to be modified by other member functions. 它允许其他成员函数修改它。 This is bad behaviour. 这是不好的行为。 Your constructor should not take a const reference. 您的构造函数不应该使用const引用。

Not only that, but your current implementation allows undefined behaviour. 不仅如此,但您当前的实现允许未定义的行为。 Even if an object that is originally declared as const is given to your Wrapper , it doesn't care. 即使最初声明为const的对象被赋予Wrapper ,它也不关心。 It casts away it's const ness and allows the other member functions to modify it. 它抛弃了它的const并允许其他成员函数修改它。 Modifying an object that was originally const is undefined behaviour. 修改最初为const的对象是未定义的行为。

† See 6502's comment †见6502的评论

It doesn't really matter that the ctor won't alter the object in the ctor , what happens after the ctor is done is why you need a non- const object pointer to B . 它并不真正重要的是, ctor不会改变的对象ctor ,会发生什么情况后, ctor完成就是为什么你需要一个非const对象指针B So it has to do with ownership and lifetime of the B object passed in: if you want to take ownership (via the & reference, then the object must be non- const because it can be altered. If you want to simply copy the B object passed in, then don't use a refernce, pass by value and store a pointer to the copy. 所以它与传入的B对象的所有权和生命周期有关:如果你想获得所有权(通过& reference,那么对象必须是非const因为它可以被改变。如果你想简单地复制B传入的对象,然后不使用引用,按值传递并存储指向副本的指针。

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

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