首页 文章

覆盖非虚方法

提问于
浏览
48

让我们假设Visual C 2010中的这种情况:

#include <iostream>
#include <conio.h>

using namespace std;

class Base
{
public:
    int b;
    void Display()
    {
        cout<<"Base: Non-virtual display."<<endl;
    };
    virtual void vDisplay()
    {
        cout<<"Base: Virtual display."<<endl;
    };
};

class Derived : public Base
{
public:
    int d;
    void Display()
    {
        cout<<"Derived: Non-virtual display."<<endl;
    };
    virtual void vDisplay()
    {
        cout<<"Derived: Virtual display."<<endl;
    };
};

int main()
{
    Base ba;
    Derived de;

    ba.Display();
    ba.vDisplay();
    de.Display();
    de.vDisplay();

    _getch();
    return 0;
};

从理论上讲,这个小应用程序的输出应该是:

  • 基础:非虚拟显示 .

  • Base:虚拟显示 .

  • Base: Non-virtual display.

  • 派生:虚拟显示 .

因为Base类的Display方法不是虚方法,所以Derived类不能覆盖它 . 对?

问题是当我运行应用程序时,它会打印出来:

  • 基础:非虚拟显示 .

  • Base:虚拟显示 .

  • Derived: Non-virtual display.

  • 派生:虚拟显示 .

所以要么我不理解虚拟方法的概念,要么在Visual C中发生奇怪的事情 .

有人可以帮我解释一下吗?

3 回答

  • 1

    是的你有点误解了:

    纯虚函数:

    virtual void fun1()=0 - >必须在派生类中重写

    虚拟功能:

    virtual void fun2() - >可以被覆盖

    正常功能:

    void fun3() - >不要覆盖它

    为了实现运行时多态性,您需要覆盖c中的虚函数

  • 68

    我认为在静态与动态绑定的上下文中查看它可能也更好 .

    如果该方法是非虚拟的(默认情况下它已经在C语言中与Java不同),则该方法在编译时绑定到它的调用者,这不可能知道将在运行时指向的实际对象 . 因此,变量类型是所有重要的“基础” .

  • 3

    是的,你有点误会了 .

    在这种情况下,派生类上的同名方法将隐藏父方法 . 您可以想象,如果不是这种情况,尝试创建一个与基类非虚方法同名的方法应该会抛出错误 . 这是允许的,这不是问题 - 如果你直接调用方法就会被称为罚款 .

    但是,作为非虚拟的,不会使用允许多态的C方法查找机制 . 因此,例如,如果您创建了派生类的实例,但通过指向基类的指针调用了'Display'方法,则将调用base的方法,而对于'vDisplay',将调用派生方法 .

    例如,尝试添加以下行:

    Base *b = &ba;
    b->Display();
    b->vDisplay();
    b = &de;
    b->Display();
    b->vDisplay();
    

    ...并按预期观察输出:

    基础:非虚拟显示 . 基地:虚拟展示 . 基础:非虚拟显示 . 派生:虚拟显示 .

相关问题