当一个函数没有修改一个对象参数时,即使被引用的对象不是真的不变,我总是让它要求一个常量引用。这是错的吗?
对于包装类,我想写一下:
template<class B>
class Wrapper{
private:
B* base_;
public:
Wrapper(const B& b) { base_ = const_cast<B*>(&b); }
void ModifyBase();
};
构造函数不修改基数,因此它要求持续引用。
包装器有一些方法需要修改基类,因此它需要存储一个非常量指针(因此转换)。
我觉得我的解决方案不是最好的。
有更好的方法吗?
是否有任何公认的惯例?
答案 0 :(得分:9)
当您选择参数作为const
参考时,您会告诉用户&#34;您可以相信,如果您传递给我一个对象,它将不会被修改[通过此参考]†&#34;你应该尽可能经常这样做,因为用户可以更多地了解你的功能,并且只是通过查看类型才能做到。此外,传递可变引用可能会导致代码难以推理。
但是,在你的问题中,你的const
并没有说实话。它抛弃了const
并存储了一个非const
指针 - 这意味着该对象很可能会被修改。你欺骗了用户!构造函数本身对该对象没有任何作用并不重要。它允许其他成员函数修改它。这是不好的行为。您的构造函数不应该使用const
引用。
不仅如此,您当前的实现还允许未定义的行为。即使最初声明为const
的对象被提供给您的Wrapper
,它也不会关心。它抛弃了它的const
并允许其他成员函数修改它。修改最初为const
的对象是未定义的行为。
†见6502的评论
答案 1 :(得分:1)
ctor
不会改变ctor
中的对象并不重要,ctor
完成后会发生什么,这就是为什么你需要非const
1}}指向B
的对象指针。所以它与传入的B
对象的所有权和生命周期有关:如果你想获得所有权(通过&
引用,那么该对象必须是非const
,因为它如果你想简单地复制传入的B
对象,那么就不要使用引用,按值传递并存储指向副本的指针。