3

在向上转换派生类的指针后,派生类的虚方法仍然被调用,这在我看来是错误的,因为切片应该发生。你能评论一下这段代码有什么问题吗?

class Base
{
public:
    virtual void Hello() { cout << "Hello Base" << endl; }
};

class Derived: public Base
{
public:
    void Hello() { cout << "Hello Derived" << endl; }
};

int main()
{
    Derived* der = new Derived;
    Base* base = dynamic_cast<Base*> (der);
    if (base) base->Hello();
}

输出:你好派生

4

2 回答 2

3

切片没有发生,因为您没有使用 的任何值Base,只是指向它的指针。

这会导致切片:

Base base = *der;

但是如果你想调用一个函数并抑制动态调度,你可以这样做:

base->Base::Hello();

要调用的函数是静态指定的。当然,这der也适用于避免中间人。


dynamic_cast在这里不需要。您可以隐式向上转换,因为这在编译时可以轻松验证。您可以使用static_castto downcast,但要确保这实际上是正确的;dynamic_cast只是一个检查版本。

于 2012-09-06T05:02:50.710 回答
2

指针转换是关于静态类型系统的,它在编译时是安全的。例如,铸造告诉编译器“相信我”。它在运行时没有任何影响。更好的转换操作,如 dynamic_cast 提供一些运行时检查(除非有意义,否则不要这样做),但这仍然不会影响多态性,它只是更合格的“相信我”......除非我这样做,否则相信我一些疯狂的东西。

多态性是关于在运行时做正确的事情。当您通过指针调用虚方法时,它将运行对对象实例执行正确的操作。

在 C++ 中,您可以使用 :: 运算符请求特定的分辨率,但这通常保留用于实现细节。

于 2012-09-06T04:49:34.873 回答