这个类是多态的。 为什么两者都打印相同的输出?
class A
{
public:
virtual void P(){ cout << "A" << endl; }
};
class B : public A
{
public:
void P()override{
cout << "B" << endl;
}
B(){ cout << "Created B" << endl; s = "Created by B"; }
string s;
};
主要: 变式1:
A* a = new B(); // Created B
B* b = static_cast<B*>(a);
b->P(); B
cout<<b->s<<endl; // Created by B
变种2:
A* a = new B();
B* b = dynamic_cast<B*>(a);
if (b){
b->P();
cout << b->s << endl; // Prints same
}
答案 0 :(得分:8)
你的两个例子都会做同样的事情,那很好。请尝试使用此功能:
A* a = new A();
在这种情况下,static_cast
将“成功”(虽然它是未定义的行为),而dynamic_cast
将“失败”(通过返回nullptr,您已经检查过)。
您的原始示例没有显示任何有趣的内容,因为它们都成功并且是有效的演员。与dynamic_cast的区别在于它允许您检测无效的强制转换。
如果您想了解 dynamic_cast
如何做到这一点,请阅读RTTI,运行时类型信息。这是一些额外的簿记,C ++在某些情况下会检查对象的类型(这对于此很重要,如果你使用typeid()
)。
答案 1 :(得分:1)
在这种情况下,static_cast
在语义上等同于dynamic_cast
。
static_cast
&lt; new_type &gt; (表达)2)如果 new_type 是某个D类和D类的指针或引用 表达式的类型是指向其非虚拟基础的指针或引用 B,static_cast执行向下转发。这样的
static_cast
没有 运行时检查以确保对象的运行时类型实际为D, 并且只有在这个前提条件得到保证的情况下才可以安全使用 其他方法,例如实现静态多态时。安全 可以使用dynamic_cast
进行向下转换。
dynamic_cast
&lt; new_type &gt; (表达)5)如果表达式是多态类型
Base
的指针或引用,new_type
是运行时类型Derived
的指针或引用 执行检查:a)表达式指向/标识的派生对象最多 检查。如果,在该对象中,表达式指向/指向公众
Derived
的基数,如果只导出Derived
类型的一个子对象 从表达式指向/标识的子对象,然后是结果 施法点/指的是Derived
子对象。 (这被称为 一个“垂头丧气”。)[...]
c)否则,运行时检查失败。如果
dynamic_cast
用于指针,类型的空指针值 返回 new_type 。如果它用于引用,则例外std::bad_cast
被抛出。
最后一个条款使dynamic_cast
更安全,因为你可以检查演员表是否不成功:
Base* b1 = new Base;
if(Derived* d = dynamic_cast<Derived*>(b1))
{
std::cout << "downcast from b1 to d successful\n";
d->name(); // safe to call
}