当您想要将类型从A 转换为B 时,您有两种语法来定义转换:
class B
{
public:
B(A); # Conversion constructor.
};
或
class A
{
public:
operator B(); # Conversion operator.
};
对于这样的情况:
void f(B b);
int main()
{
A a;
f(a);
}
如果第一个版本存在,它会创建一个类B 的临时对象,使用a 作为参数。如果存在第二个版本(当然,你实现了它),它会调用类A 的operator B() 来从a 创建一个B 类型的对象。如果两者都存在,编译器会向您抛出歧义错误消息。
关于向下/向上转换,隐式转换允许向上转换(如果源和目标类型是引用/指针),即使目标基类是源的不可访问(私有)基类。隐式转换还允许从非 const 源类型转换为 const 目标类型,或者也允许从右值转换为左值等等。
简而言之,这些是隐式转换的规则。更完整的指南(考虑内置与用户定义的类型和内置转换)是here。
如果您使用 C++ 类型转换:
f(static_cast<B>(a));
几乎相同,但有一些区别:如果B 是a 的不可访问的(私有)基础,则不允许强制转换。另一个区别是允许向下转换而无需运行时检查(如果B 是A 的派生类,它允许转换,即使a 实际上不是B 类型的对象)。这是允许的,因为运行时检查很慢,因此,如果您知道 a 实际上是 B 类型,则可以安全地应用强制转换而无需运行时检查。
其他铸件有:
const_cast<B>(a)
只能从 const 更改为 non-const,反之亦然。
reinterpret_cast<B>(a);
铸造一切。几乎不涉及任何规则。如果从a 到B 的转换不存在,它只会占用a 的内存区域并将其作为B 类型的对象返回。它是目前最快的演员。
dynamic_cast<B>(a);
带有运行时检查的向下转换(两种类型都必须是引用或指针)。如果a 的真实类型不是B(甚至不是a 的真实类型的基类),则抛出/返回异常或空指针(根据a 或B是引用或指针)。
最后,C-casting:
f((B)a);
C 转换所做的是尝试不同的转换(dynamic_cast 除外,并且还允许转换为无法使用的基类)并使用第一个有效的转换。我会说 C 转换和隐式转换一样强大。
函数调用语法的显式转换:
f(B(a));
在行为上等同于 C-casting。