C++多态/继承问题:基本函数与虚函数的重新定义

Rus*_*sel 10 c++ inheritance virtual-functions

我知道派生类可以简单地"重新定义"基类成员函数,并且当调用派生类对象的函数时,使用派生类中定义的函数,但是...这不会呈现"虚拟" "关键字冗余?我已经读过这两种情况之间的一些明显的显着差异(即:如果你有一个指向派生类的基类指针而你调用一个函数,如果它是虚拟的,那么将调用派生类函数,但如果没有,则将调用基类函数).

换句话说,能够将成员函数重新定义为非虚函数的目的是什么,这是一种常用的做法吗?

就个人而言,在我看来它会变得非常混乱.

谢谢!

vz0*_*vz0 7

对于最常见的OOP语言(Java,SmallTalk,Python等),最常见的方法是默认情况下将每个成员函数都设置为virtual.

缺点是每次进行虚拟呼叫时都会有很小的性能损失.因此,C++允许您选择是否要将方法定义为虚拟方法.

但是,虚拟和非虚拟方法之间存在非常重要的差异.例如:

class SomeClass { ... };
class SomeSubclassOfSomeClass : public SomeClass { ... };
class AnotherSubclassOfSomeClass : public SomeClass { ... };

SomeClass* p = ...;

p->someVirtualMethod();

p->someNonVirtualMethod();
Run Code Online (Sandbox Code Playgroud)

someVirtualMethod调用时执行的实际代码取决于引用指针的具体类型p,完全取决于SomeClass子类重新定义.

但是在someNonVirtualMethod调用上执行的代码是明确的:始终是on SomeClass,因为p变量的类型是SomeClass.


Ste*_*eve 1

它将适用于派生类的实例和指向派生类的指针。但是,如果将派生类传递给一个采用指向 Base 的指针的函数,则将调用该函数的 Base 版本。这可能是不可取的。例如,以下将返回 5

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

class Base
{
public:
    int Foo(){return 5;}
};

class Derived:public Base
{
    int Foo(){return 6;}
};

int Func(Base* base)
{
    return base->Foo();
}

int _tmain(int argc, _TCHAR* argv[])
{
    Derived asdf;

    std::cout << Func(&asdf);
    getch();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是因为虚拟的工作方式。当对象有虚拟调用时,当您调用虚拟函数时,会在 v 表中查找正确的函数。否则,您实际上并没有继承,您的 Base 指针的作用就像基类而不是派生类。