简体   繁体   English

覆盖非虚拟方法

[英]Overriding non-virtual methods

Let's assume this scenario in Visual C++ 2010: 让我们在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;
};

Theoretically, the output of this little application should be: 从理论上讲,此小应用程序的输出应为:

  • Base: Non-virtual display. 基本:非虚拟显示。
  • Base: Virtual display. 基本:虚拟显示。
  • Base: Non-virtual display. 基本:非虚拟显示。
  • Derived: Virtual display. 派生:虚拟显示。

because the Display method of the Base class is not a virtual method so the Derived class should not be able to override it. 因为Base类的Display方法不是虚拟方法,所以Derived类不能覆盖它。 Right? 对?

The problem is that when I run the application, it prints this: 问题是,当我运行该应用程序时,它显示以下内容:

  • Base: Non-virtual display. 基本:非虚拟显示。
  • Base: Virtual display. 基本:虚拟显示。
  • Derived: Non-virtual display. 派生:非虚拟显示。
  • Derived: Virtual display. 派生:虚拟显示。

So either I didn't understand the concept of virtual methods or something strange happens in Visual C++. 因此,要么我不了解虚拟方法的概念,要么在Visual C ++中发生一些奇怪的事情。

Could someone help me with an explanation? 有人可以帮我一个解释吗?

Yep, you are misunderstanding a little. 是的,你有点误会。

The method of the same name on the derived class will hide the parent method in this case. 在这种情况下,派生类上同名的方法将隐藏父方法。 You would imagine that if this weren't the case, trying to create a method with the same name as a base class non-virtual method should throw an error. 您可能会想,如果不是这种情况,尝试创建与基类非虚拟方法同名的方法会引发错误。 It is allowed and it's not a problem - and if you call the method directly as you have done it will be called fine. 它是允许的,这不是问题-如果您直接完成该方法,则将其命名为罚款。

But, being non-virtual, C++ method lookup mechanisms that allow for polymorphism won't be used. 但是,由于是非虚拟的,因此不会使用允许多态的C ++方法查找机制。 So for example if you created an instance of your derived class but called your 'Display' method via a pointer to the base class, the base's method will be called, whereas for 'vDisplay' the derived method would be called. 因此,例如,如果您创建了派生类的实例,但通过指向基类的指针调用了“ Display”方法,则将调用基类的方法,而对于“ vDisplay”,将调用派生方法。

For example, try adding these lines: 例如,尝试添加以下行:

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

...and observe the output as expected: ...并按预期观察输出:

Base: Non-virtual display. 基本:非虚拟显示。
Base: Virtual display. 基本:虚拟显示。
Base: Non-virtual display. 基本:非虚拟显示。
Derived: Virtual display. 派生:虚拟显示。

Yes you have misunderstood a little: 是的,您有点误会了:

Pure virtual functions: 纯虚函数:

virtual void fun1()=0 -> must be overridden in the derived class virtual void fun1()=0 >必须在派生类中重写

Virtual functions: 虚函数:

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

Normal functions: 正常功能:

void fun3() -> don't override it void fun3() ->不要覆盖它

In order to achieve runtime polymorphism you need to override virtual functions in c++ 为了实现运行时多态,您需要重写c ++中的虚函数

I think it might be also better to look at it in the context of static vs dynamic binding. 我认为在静态绑定与动态绑定的上下文中查看它可能会更好。

If the method is non-virtual (it's already by default in C++ unlike Java), then the method binds to it's caller at compile time which is impossible to know the actual object that will be pointed at runtime. 如果该方法是非虚拟的(与Java不同,C ++中已经默认使用该方法),则该方法在编译时绑定到其调用者,这是不可能知道将在运行时指向的实际对象的。 So, variable type is all that matters which is the 'Base'. 因此,变量类型是所有重要的基础。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM