【发布时间】:2012-06-19 16:30:30
【问题描述】:
const_cast 和 c 风格转换 (ObjectType) 之间有实际区别吗?
【问题讨论】:
标签: c++
const_cast 和 c 风格转换 (ObjectType) 之间有实际区别吗?
【问题讨论】:
标签: c++
const_cast 传达了有关转换背后意图的特定信息,而 C 转换不能。
如果您不小心尝试将const_cast 用于添加或删除const 或volatile 以外的其他目的,编译器将帮助您显示错误消息。
此外,const_cast 是可搜索的,这与 C 风格的演员表不同。
【讨论】:
const_cast 只能添加或删除 const-ness(或 volatile-ness,尽管这种情况不太常见)。
除了dynamic_cast 之外,C 风格的演员表可以做任何“新”演员表一样的事情(它可以做一些他们都做不到的事情,尽管在这里并不真正相关)。
【讨论】:
C++ 中的 C 风格转换尝试静态转换、重新解释转换、常量转换或这些的组合。
建议避免使用 C 类型转换,主要是因为...
【讨论】:
C 演员阵容比其他演员组合更强大。在某些极端情况下,唯一的选择是 C 风格的强制转换(例如,向上转换到私有库),尽管可以争辩说您无论如何都不应该编写该代码......
reinterpret_cast 通常会使用单继承。对于多重继承,它通常适用于一个基类,但对所有其他基类都不起作用(只有 一个 基类可以驻留在派生对象的开头)。
static_cast,其中忽略了访问说明符。考虑struct D : A, B, private C {} d; 的输出(void*)(C*)&d 和(void*)reinterpret_cast<C*>(&d) 会有所不同。在 C 转换的情况下,指针将引用实际的 C 子对象,而在 reinterpret_cast 的情况下,它将(很可能,标准不保证)引用 D 对象的位置(或一垒)
同样的动作。 C 风格的强制转换可以完全抛弃 const。
const_cast 的原因是它可以作为一个可搜索的危险信号,用于搜索并仔细审查/惩罚有罪的人。这个想法是 C++ 比 C 更加类型紧密。因此,故意违反类型系统(例如违反 const 正确性),即使不是不可能,也很容易被发现。
使这种违反类型安全的行为完全不可能会破坏太多的向后兼容性。
【讨论】:
const_cast 只能修改参数的 const-ness(或 volatile-ness),而不是 basic 类型。所以
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-style cast 将 cv-qualified T* 修改为 U* 没有任何问题。
【讨论】:
const_cast 受到更多限制,除了更改 const-ness 之外,不会让您做任何事情。这使它更安全,即更不容易发生事故。
此外,它更容易搜索。
【讨论】: