const_cast做了什么不同的事情?

3
const_cast和C风格的强制类型转换(ObjectType)之间是否存在实际差异?
6个回答

11

const_cast传达了一种C风格转换所不能表达的转换意图。

如果您误用const_cast进行除添加或移除constvolatile之外的其他用途,则编译器会通过错误消息帮助您。

此外,const_cast是可搜索的,而C风格转换不可。


4

const_cast 只能添加或移除 const(或者 volatile,虽然这种情况很少出现)。

C 风格的转换可以像任何“新”的转换一样执行相同的操作,除了 dynamic_cast(它可以执行一些其他转换无法执行的操作,但这在此处并不重要)。


@davidrodríguez-dribeas:过于追求严谨几乎总是会得到一两个赞(尽管有时只是来自同样追求严谨的人... :-) - Jerry Coffin

2

C++中的C风格转换尝试进行静态转换、重新解释转换、常量转换或这些转换的组合。

建议避免使用C转换,主要原因是...

  • 重新解释转换和常量转换很少使用,因此强调你正在做什么是很好的选择,
  • 在其他情况下,当您需要静态转换时,明确写出它可以为您提供与C转换相比的额外编译时检查。

C 强制类型转换比其他组合方式更加强大。在某些边缘情况下,唯一的选择是使用 C 风格的强制类型转换(例如向私有基类进行上转型),尽管可以争论你不应该编写那样的代码... - David Rodríguez - dribeas
@DavidRodríguez-dribeas,这很有趣,但我无法重现此问题;http://ideone.com/38Nyb - Kos
@Kos:虽然不能保证,但reinterpret_cast通常适用于单一继承。对于多重继承,它通常适用于一个基类,但对于其他所有基类都会失败(只有一个基类可以位于派生对象的开头)。 - Jerry Coffin
@Kos:区别在于,在这种情况下的C样式转换等同于忽略访问说明符的static_cast。考虑 struct D : A, B, private C {} d;(void*)(C*)&d(void*)reinterpret_cast<C*>(&d) 的输出将不同。在C转换的情况下,指针将引用实际的C子对象,而在reinterpret_cast的情况下,它将(很可能,标准不保证)引用D对象(或第一个基类)的位置。 - David Rodríguez - dribeas

1

const_cast 只能修改参数的 常量性(或 易变性),而不能修改其 基本 类型。因此

 const T *tc = f();
 volatile T *tv = g();

 U *ua = const_cast<U*>(tc); //error
 U *ub = const_cast<U*>(tv); //error

 U *ub = (U*)(tc); //okay
 U *ub = (U*)(tv); //okay

因此,C风格的转换可以修改带有cv限定符的T*U*而不会出现任何问题。


1

同样的操作。C风格的转换可以将const全部去除。

使用const_cast的原因是它可以作为可搜索的红旗,用于搜索并仔细审查/惩罚有罪者。这个想法是,C++比C更加类型严格。因此,如果故意违反类型系统(例如违反const正确性),即使不是不可能,也很容易被发现。

使这种类型安全违规完全不可能会破坏太多的向后兼容性。


0

const_cast更为受限,除了更改常量性以外,不允许您执行任何其他操作。这使它更安全,即更少出现意外。

此外,它更易于搜索。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接