C++中的函数覆盖在没有"虚拟"的情况下工作

the*_*rer 1 c++ virtual overriding

我有一个包含一些函数的类(没有虚函数),还有两个类公开继承该类.在这两个子类中,我重写了基类的相同功能.

在main(位于同一文件)中创建所有三个类的对象之后,我使用baseclass对象调用原始函数,并使用derivedclass对象调用覆盖的函数.

我期待所有3个函数调用从基类运行原始函数(因为我没有在代码中的任何地方使用'virtual'),但我实际上让该函数的每个版本都按照它所在的类运行定义(3个不同版本).

我有类Base和Derived如下:

struct Base
{
   void foo();
};

struct Derived : Base
{
   void foo();
};
Run Code Online (Sandbox Code Playgroud)

在主要:

int main()
{
   Derived d;
   d.foo();
}
Run Code Online (Sandbox Code Playgroud)

我认为如果不使用'virtual',d.foo()应该运行Base :: foo().

Lig*_*ica 10

不是 "压倒一切"......并不是必须的.

struct Base
{
   void foo();
};

struct Derived : Base
{
   void foo();
};

int main()
{
   Derived d;
   d.foo();
}
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,那么你期望执行它Base::foo(),因为函数不是虚拟的,因此不会覆盖另一个.

但是,在这里,您不需要虚拟调度:继承规则只是声明您将为您运行它的对象的类型获得正确的函数.

当您需要虚拟调度/覆盖时,情况略有不同:当您使用间接时:

int main()
{
   Base* ptr = new Derived();
   ptr->foo();
   delete ptr;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,结果将是Base::foo()被调用,因为表达ptr->foo()不知道*ptr真是一个Derived.它只知道ptr是一个Base*.

这是添加virtual(并且,在这样做,使一个函数覆盖另一个)的地方使魔术发生.

  • 你的派生应该是从基础派生的吗? (2认同)