是的,我知道使用 dynamic_cast
进行向下转型如果 Base
不具备多态性将无法编译,但我的问题并不是关于这个。
class Base {
public:
virtual void bar()
{
cout << "bar\n";
}
};
class Derived: public Base {
public:
void foo()
{
cout << "foo\n";
}
};
int main()
{
Base *pb;
Derived *pd;
pb = new Derived; //Base* points to a Derived object
pd = dynamic_cast<Derived*>(pb);
pd->foo(); //outputs foo
pb = new Base; //Base* points to a Base object
pd = dynamic_cast<Derived*>(pb);
pd->foo(); //outputs foo, too. Why?
}
我原以为当 pb = new Derived;
时,pb
实际上指向堆中的一个 Derived
对象。在执行 pd = dynamic_cast<Derived*>(pb);
后,pd
也指向该 Derived
对象,因此 pd->foo()
应该是可以的。
但是当 pb = new Base;
时,pb
指向堆中的一个 Base
对象,那么在执行 pd = dynamic_cast<Derived*>(pb);
后,pd->foo()
怎么可能起作用呢?难道 dynamic_cast
将堆中的 Base
对象变成了一个 Derived
对象吗?
pd->foo();
时,无论pd
是否为NULL
,foo()
都会被调用吗? - Alcottthis
参数将会被传递为 NULL(因为pd
的值就是 NULL)。因此,在 Rohan 的例子中,当你访问a
时,会出现预期的崩溃。 - littleadvDerived::foo
,与pd无关,因此如果pd == NULL
,那么pd->foo()
应该就像NULL->foo()
一样,对吗?那么编译器怎么知道我想调用Derived::foo()
而不是其他任何foo()
呢?只是因为pd
的类型是Derived *
吗? - Alcottpd->foo()
这样的调用时,编译器执行的是类似于Runtime.invoke(Derived.foo, pd)
的操作。这并不是真正发生的事情,但我试图展示的是,方法的查找是基于类型而不是实例完成的。实例变得只是传递给方法的“参数”,它可能是null
。 - Rohan Prabhu