为什么指向具有重写方法的派生类对象的基类指针调用基类方法?

时间:2018-08-01 05:28:02

标签: c++ inheritance virtual

#include<iostream>
using namespace std;

class Base
{
public:
    void show() { cout<<" In Base \n"; }
};

class Derived: public Base
{
public:
    void show() { cout<<"In Derived \n"; }
};

int main(void)
{
    Base *bp = new Derived;
    bp->show(); // RUN-TIME POLYMORPHISM
    return 0;
}

在上面的代码中,show()在基类中声明,并在派生类中被覆盖。基类指针bp指向派生类对象。现在,当bp调用非虚拟show()函数时。

输出:

In Base

但是,bp指向派生类,那么为什么要调用基函数而不是派生类函数呢?

8 个答案:

答案 0 :(得分:4)

  

// RUN-TIME POLYMORPHISM

在C ++中是可选的。为了在运行时以多态方式解析函数调用,程序员必须通过将其标记为virtual来明确表示需要这样做。

原因是动态调度永远不会没有成本,而C ++设计的主要内容是“您不用为不需要的东西付钱”。您必须说确实需要它才能启用它。

答案 1 :(得分:2)

您需要将show()虚拟化,以允许运行时多态性启动。

virtual void show() { cout<<" In Base \n"; }

答案 2 :(得分:2)

作为对此评论的补充,以补充此处发布的其他答案:

  

我知道,但是基本指针指向派生类,那么为什么要调用基本函数?

请参阅此帖子:https://stackoverflow.com/a/50830338/5743288

因此,如果您要执行此操作,则可以:

Derived *dp = new Derived;
dp->show();

您将获得以下输出:

In Derived

即使没有将show()声明为virtual(因为编译器将随后知道您要调用的方法 )。

因此,正如其他人指出的那样,如果您想要服务就必须付出代价(尽管即使使用原始代码,编译器也可能足够聪明,无论如何仍要优化虚拟函数调用,请参见{{3 }}。

答案 3 :(得分:1)

大多数人已经回答过,您需要声明一个函数为<View> { this.renderAlbums() } //it will return react element which can be rendered. </View> ,以便在代码执行时在运行时进行绑定。 我想补充一点,如果没有虚拟,要调用的方法是在编译时确定的,它将选择您声明了变量/指针类型的类的方法。您的情况是virtual类类型。

此外,我们想提供一个易于阅读的链接,该链接可以帮助您清除C ++中的运行时多态性概念:https://www.geeksforgeeks.org/virtual-function-cpp/

答案 4 :(得分:1)

此处的核心问题是show方法在派生类中没有被覆盖。从C ++ 11开始,您可以使用override说明符来确保该方法确实覆盖了某些内容,因此编译器将为您检测到此问题:

class Derived: public Base
{
public:
    void show() override { cout<<"In Derived \n"; }
};
  

prog.cc:13:10:错误:“ void Derived :: show()”标记为“覆盖”,但未覆盖

为了覆盖方法,应在基类中将其声明为virtual

class Base
{
    public: virtual
    void show() { cout<<" In Base \n"; }
};

答案 5 :(得分:0)

这实际上是所谓的运行时多态。并且在C ++中,程序员可以根据提供给基类​​指针的对象来酌情调用基类或派生类的所需函数。

与指向任何派生类对象的基类指针无关。如果要调用的函数是非虚拟的,则始终将基类函数调用为基类指针。

要从基类指针调用派生类函数,必须将该函数标记为virtual

答案 6 :(得分:0)

int main(void)
{
    Base *bp = new Derived;
    bp->show(); // RUN-TIME POLYMORPHISM
    return 0;
}

编译器在编译时将其与基类对象绑定     “新派生”传递对象到基础,但是它与基础对象绑定,它引用相同的类     一次,如果添加虚拟绑定,则会在运行时发生,一旦派生对象传递,它就会与驱动类绑定

答案 7 :(得分:0)

在c ++中,即使您使基类指针指向派生类对象,它仍然会从基类中调用该函数,这是因为Early绑定,因此为了实现Late绑定,请在基本类别为虚拟。 即虚拟虚空show() { ....... }
现在,o / p将为“ In Derived”。