方法是否被覆盖或重载?

Is the method overridden or overloaded?

我们有两个 class。

class A{
public:
  void fun(){
     cout<<"Parent\n";
  }
};
class B:public A{
public:
  void fun(){
     cout<<"Child\n";
  }
};

我正在尝试确定函数 fun() 是否会被视为 overloadedoverridden。 我尝试使用 override 关键字,它说该方法未被覆盖。但是我想知道 override 关键字是否只有在父 class 中的函数写成 virtual 时才有效,并且在上述情况下是否可以认为该函数被覆盖。

此外,我想知道重写方法 always 是否意味着 late-binding/runtime-polymorphism?

B::fun 都不重载 也不重载 A::fun。它 隐藏了 它。这不是覆盖,因为您仍然可以通过将 B 视为 A

来在 B 上获得 A::fun 行为
B x;
A &y = x;
y.fun(); // outputs Parent

当您尝试通过 A 接口访问 fun 方法时,您会遇到 Parent 行为。如果 A::fun 声明为 virtual,那么 然后 B::fun 将覆盖它,并且通过 A 接口访问的 fun 方法将输出 Child.

重载和隐藏的区别在这里不是很清楚,因为参数列表是一样的,但是要考虑层级

struct A {
    void foo(int i) { std::cout << i << "\n"; }
};
struct B : A {
    void foo(std::string const &s) { std::cout << std::quoted(s) << "\n"; }
};

如果 B::foo 只是 超载 A::foo 那么这会起作用

B x;
x.foo(5);

但事实并非如此。请注意 x 仍然 具有 foo(int) 方法。

A &y = x;
y.foo(5); // works

您只是无法通过 B 界面访问它。这是因为重载决策仅在同一个 class 中声明的成员集中进行。如果 class 没有声明名称的成员,那么它会转到基础 classes,但是如果 class 确实声明了名称和它们的 none匹配,决议就在那里失败了。 (即删除 B::foo 会使 x.foo(5) 起作用。)

您可以 请求 重载而不是使用 using 指令从语言中隐藏,但是再次覆盖是不可能的,除非 A::funvirtual(并且 B::fun 需要与 A::fun 具有相同的参数列表)。

struct B : A {
    using A::foo;
    void foo(std::string const &s) { std::cout << std::quoted(s) << "\n"; }
};

(P.S。关于注释,C++中的技术术语确实是hidingShadowing可能是这个词在其他语言中用于此行为,但 C++ 标准使用“隐藏”。)