为什么在向上转换后调用派生类的虚方法?

时间:2012-09-06 04:46:43

标签: c++ derived-class upcasting

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

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();
}

输出:Hello Derived

2 个答案:

答案 0 :(得分:3)

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

这会导致切片:

Base base = *der;

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

base->Base::Hello();

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


此处不需要dynamic_cast。您可以隐式地转发,因为这在编译时很容易验证。您可以使用static_cast向下转发,但是由您决定确实这是正确的; dynamic_cast只是该版本的检查版本。

答案 1 :(得分:2)

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

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

在C ++中,您可以使用::运算符请求特定的解析,但这通常是为实现细节保留的。