【问题标题】:Is the method overridden or overloaded?方法是被覆盖还是重载?
【发布时间】:2021-09-30 22:25:34
【问题描述】:

我们有两个班级。

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

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

另外,我想知道重写方法 always 是否意味着后期绑定/运行时多态性?

【问题讨论】:

  • 覆盖。仅当方法具有相同的签名(但提供的参数不同)时才会发生重载。
  • 两者都不是。它被遮住了。
  • @Urmzd 是不是像非虚方法一样不能被覆盖?
  • @rustyx 你能解释一下吗?一些参考资料?
  • @AdrianMole - 这不是覆盖。这里的人正在尝试学习 C++,所以最好坚持 C++ 术语。此代码中没有覆盖。只有一种方法隐藏另一种。简单明了。

标签: c++ oop inheritance overriding overloading


【解决方案1】:

B::fun 既不重载也不覆盖A::fun。它隐藏它。这不是覆盖,因为您仍然可以通过将 B 视为 A 来获得 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 界面访问它。这是因为重载决议只在同一类中声明的成员集之间完成。如果一个类没有声明名称的成员,那么它会转到基类,但如果该类确实声明了名称并且它们都不匹配,那么解析就在那里失败。 (即删除 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"; }
};

(PS 关于 cmets,C++ 中的技术术语确实是 hidingShadowing 可能是其他语言中用于此行为的词,但 C++ 标准使用“隐藏”。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多