方法是否被覆盖或重载?
我们有两个班级。
class A{
public:
void fun(){
cout<<"Parentn";
}
};
class B:public A{
public:
void fun(){
cout<<"Childn";
}
};
我想弄清楚是否fun()会考虑该功能overloaded或overridden. 我尝试使用override关键字,它说该方法未被覆盖。但是我想知道该override关键字是否仅在父类中的函数被编写为virtual以及在上述情况下该函数是否可以被视为被覆盖时才有效。
另外,我想知道重写方法是否总是意味着后期绑定/运行时多态性?
回答
B::fun 既不重载也不覆盖A::fun。它隐藏它。这不是一个重写,因为你仍然可以得到A::fun一个行为,B通过将其视为一个A
B x;
A &y = x;
y.fun(); // outputs Parent
当您尝试fun通过A接口访问该方法时,您将获得该Parent行为。被A::fun声明virtual,然后 B::fun将覆盖它并且fun通过A接口访问的方法将输出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::fun是virtual(并且B::fun需要具有与 相同的参数列表A::fun)。
struct B : A {
using A::foo;
void foo(std::string const &s) { std::cout << std::quoted(s) << "n"; }
};
(PS关于注释,C++中的技术术语确实是隐藏。阴影可能是其他语言中用于这种行为的词,但C++标准使用“隐藏”。)