好的做法:常量到非常量的转换
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
属性并存储了一个非CC_4指针——这意味着对象很可能被修改。你欺骗了用户!构造函数本身对对象不做任何操作并不重要。它允许其他成员函数修改它。这是不好的行为。你的构造函数不应该接受const
引用。
不仅如此,您当前的实现还允许未定义行为。即使最初声明为const
的对象被赋予Wrapper
,它也不会在意。它抛弃了它的const
属性,并允许其他成员函数修改它。修改一个原来是const
的对象是未定义的行为。
†参见6502的注释
ctor
不会改变ctor
中的对象并不重要,ctor
完成后发生的事情就是为什么您需要一个指向B
的非const
对象指针。因此,它必须与传入的B
对象的所有权和生命周期有关:如果您想获得所有权(通过&
引用),那么该对象必须是非const
,因为它可以被更改。如果您想简单地复制传入的B
对象,那么不要使用引用,而是按值传递并存储指向副本的指针。
相关文章:
- 为什么下面带有非常量转换函数的代码没有歧义?
- 如何将变量内容常量转换为 std::array 的大小?
- 将结构C++成员从非常量转换为常量
- 意外 (IMO) 常量转换警告
- 警告:ISO C++禁止将字符串常量转换为'char*' [-Wwrite-strings]
- 为什么无法将常量 X 转换为 X &?
- 重载常量和非常量转换运算符返回数组类型时出现 MSVC 错误 C2593
- 将字符串常量转换为char
- 警告:ISO C++禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- 错误C2662无法从常量转换为引用
- 常量转换运算符的行为
- 如何在 C 中将多字符常量转换为整数
- 从字符串常量转换,c++ 中的指针
- 从字符串常量转换为字符*
- 在这里做常量转换安全吗
- boost序列化错误C4308:负整数常量转换为无符号类型
- 不赞成从字符串常量转换为“char*”[-Wwrite strings]
- C++非常量到常量转换编译错误
- C++-不赞成在第三方标头中从字符串常量转换为“char*”
- 空指针常量转换为右值