我可以使用覆盖非虚拟方法的方法吗?

Can i use a method overriding a non-virtual method?

本文关键字:方法 虚拟 可以使 覆盖 我可以      更新时间:2023-10-16

我试图用C++来理解一点。如果类 A 有一个非虚拟方法,而扩展 A 的类 B 覆盖了该方法,我可以创建 B 的实例并以某种方式使用 B 中定义的方法吗?是否有覆盖非虚拟方法的意义?

是否有覆盖非虚拟方法的意义?

您实际上并没有覆盖,但这是行为,即

B* b = new B();
A* a = new B();
b->method(); //Calls B's method
a->method(); // Calls A's method

因此,指针/引用类型确定调用的方法。

我可以创建 B 的实例并以某种方式使用 B 中定义的方法吗?

是的。指针/引用类型必须是 B 类型(请参阅前面的示例)。

如果不将method声明为 virtual ,则无法覆盖它,但可以隐藏它。

如果B继承自A,并重新定义A中定义的方法,则B的新实例将调用B的版本。但是,如果该方法不是虚拟的,则没有多态行为,因此如果B的实例被引用为A,则该方法将A。例如:

struct A {
    void foo () { std::cout << "A::foo" << std::endl; }
};
struct B : public A {
    void foo () { std::cout << "B::foo" << std::endl; }
};
B b;
b.foo();
A *a = &b;
a->foo();

上面代码的输出将是:

B::foo
A::foo

但是,如果foo方法是虚拟的,那么B::foo将被打印两次。

如果函数未virtual则变量的类型也决定了调度哪个实现:

#include <iostream>
using namespace std;
struct A {
    void f() { cout << "A" << endl; }
};
struct B : public A {
    void f() { cout << "B" << endl; }
};
int main(int args, char** argv) {
    B b;
    A& a = b;
    b.f();
    a.f();
    return 0;
}
  • 否,没有覆盖类 A 中的非虚拟方法的机制。
  • 是的,您可以使用范围解析运算符 A::methodName 在 B 中重载的类 A 中的非虚拟方法