[英]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.