c++ - Derived pointer to Base pointer conversion using static_cast, dynamic_cast, or explicit conversion 不会调用基函数

标签 c++ oop dynamic-cast static-cast

我有以下代码。

#include <iostream>
using namespace std;


class Base
{
public:
    virtual int f(){cout<<"Base"<<endl;}
};

class Derived:public Base
{
public:
    int f(){cout<<"Derived"<<endl;}
};

int main()
{
    Base b;
    Derived d;

    b.f(); ///base
    ((Base)d).f(); ///base

    cout<<"----------------"<<endl;

    Base *b1 = new Base;
    Base *b2 = new Derived;
    Derived *d1 = new Derived;

    b1->f(); ///base
    ((Base*)d1)->f(); ///derived
    ((Base*)b2)->f(); ///derived
    static_cast<Base*>(d1);
    d1->f();///derived
    static_cast<Base*>(b2);
    b2->f();///derived

    cout<<"----------------"<<endl;

    Base *b5 = dynamic_cast<Base*>(b2);
    Base *b6 = dynamic_cast<Base*>(d1);
    if(b5)
        b5->f(); ///derived
    if(b6)
        b6->f(); ///derived


    return 0;
}

我想问一下,为什么派生的 *d1 OR b2 指针在使用显式转换 (Base)、静态转换 (static_cast(d1)) 或动态转换 (dynamic_cast(d1) ) 转换后不会调用基类的 f() 函数。似乎每次都从派生类调用 f() 函数。

此外,奇怪的是,当我以这种方式声明对象时。转换有效并调用基本函数。

Base b;
    Derived d;

    b.f(); ///base
    ((Base)d).f(); ///base

现在,我明白从 Base 类访问 f() 的正确方法是 d->Base::f(),但我为什么要使用 dynamic_cast 或 static_cast,因为它们赢了' 将派生指针转换为基指针并调用正确的函数。如果可能的话,我需要一个详细的解释。谢谢!

最佳答案

幸运的是,对于你和我的键盘来说,解释是微不足道的:

((Base)d) 将对象 d 切片到值复制的 Base 实例。

((Base*)d1)->f() 仍然会调用派生方法,因为 Base 因此 Derived 是多态类型,虽然 ((Base*)d1) 是一个 Base* 指针,但它指向一个 Derived 对象。 static_castdynamic_cast 也是如此。

引用:https://en.wikipedia.org/wiki/Object_slicing

关于c++ - Derived pointer to Base pointer conversion using static_cast, dynamic_cast, or explicit conversion 不会调用基函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45999683/

相关文章:

java - 嵌套类匿名类

C++ 所有类的公共(public)基指针向上转型、向下转型和侧转型

c++ - 识别派生类类型的正确方法(类型实体 VS dynamic_case)

c++ - WinHttpDetectAutoProxyConfigUrl 始终失败,错误代码为 12180 (ERROR_WINHTTP_AUTODETECTION_FAILED)

c++ - 在没有移动构造函数的情况下,复制构造函数被调用?这是为什么?

c++ - 将 C++ 流用于 cout 或文本文件

javascript - 销毁构造函数实例

c++ - 这个LNK2005怎么解释?

java - 如果满足条件则调用方法重新启动而不使用循环

c++ - 将基类作为参数传递给虚函数时避免 dynamic_cast