Raj*_*sad 5 c++ inheritance casting reference derived-instances
准确地说,为什么下面的程序可以B b = (B&) a
编译并运行,而B b = (B) a
不能?
#include <iostream>
using namespace std;
class A {public: void f(){ cout<<"A"<<endl;} };
class B : public A { public: void f(){cout<<"B"<<endl;} };
void g(A a){ B b = (B&) a; b.f(); }
int main() {
B b; g(b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是否有关于转换为派生类型以及我在这里缺少的参考的内容?如果我只是强制转换为 B,则会出现编译时错误:构造函数 B(A a) 不存在。
A
因为从到 的隐式转换B
不存在,并且您也没有定义显式转换。
另一方面,引用转换是有效的,因为继承类型允许它。更准确地说,您可以在同一继承层次结构中的不同类之间进行两种方式的转换。指针也是如此。如果您需要一些进一步研究的指导,相关概念称为多态性。
但请注意,只有将类型转换为的对象才有意义。例如:B
B
B b;
A& aRef = B; // equivalent of A& ref = (A&)B;
B& bRef = (B&)aRef;
Run Code Online (Sandbox Code Playgroud)
一旦您尝试B
访问A
. 因为你的实际对象是A
,不是B
。
向上转换(从后代到上升)始终是安全的,因为继承基类的类的任何对象都是有效的基对象。然而,由于我上面解释的确切原因,向下转型是危险的,并且永远不应该使用 C 风格的转型来完成。相反,使用dynamic_cast
:
B b;
A& aRef = B;
B& bRef = dynamic_cast<B&>(aRef);
Run Code Online (Sandbox Code Playgroud)
dynamic_cast
使用 RTTI(运行时类型信息)来验证操作,std::bad_cast
如果转换无效,将抛出异常。这与dynamic_cast
ing 指针不同,在这种情况下,强制转换会返回nullptr
而不是抛出异常。