让我们假设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;
};
Run Code Online (Sandbox Code Playgroud)
从理论上讲,这个小应用程序的输出应该是:
因为Base类的Display方法不是虚方法,所以Derived类不能覆盖它.对?
问题是,当我运行应用程序时,它会打印出:
所以要么我不理解虚方法的概念,要么在Visual C++中发生奇怪的事情.
有人可以帮我解释一下吗?
sje*_*397 97
是的,你有点误解了.
在这种情况下,派生类上的同名方法将隐藏父方法.您可以想象,如果不是这种情况,尝试创建一个与基类非虚方法同名的方法应该抛出错误.这是允许的,这不是问题 - 如果你直接调用该方法就会被称为罚款.
但是,作为非虚拟的,不会使用允许多态的C++方法查找机制.因此,例如,如果您创建了派生类的实例,但通过指向基类的指针调用了'Display'方法,则将调用base的方法,而对于'vDisplay',将调用派生方法.
例如,尝试添加以下行:
Base *b = &ba;
b->Display();
b->vDisplay();
b = &de;
b->Display();
b->vDisplay();
Run Code Online (Sandbox Code Playgroud)
...并按预期观察输出:
基础:非虚拟显示.
基地:虚拟展示.
基础:非虚拟显示.
衍生:虚拟显示.
小智 6
是的,您有点误会了:
纯虚函数:
virtual void fun1()=0 ->必须在派生类中重写
虚函数:
virtual void fun2() ->可以被覆盖
正常功能:
void fun3() ->不要覆盖它
为了实现运行时多态,您需要重写c ++中的虚函数
我认为最好在静态绑定与动态绑定的上下文中查看它。
如果该方法是非虚拟的(与 Java 不同,它在 C++ 中已经是默认值),则该方法在编译时绑定到它的调用者,这是不可能知道将在运行时指向的实际对象。因此,变量类型才是最重要的,即“基础”。