我对以下情况有点困惑,它们是覆盖函数 copy
而不是重载的正确方法,还是它们都是正确的?
class Base{
public:
virtual Base* copy(Base* b){...}
};
class Derived:public Base{
public:
virtual Base* copy(Base* b){...}//I know this should work
// but how about the followings?
//virtual Base* copy(Derived* b){...}
//virtual Derived* copy(Base* b){...}
//virtual Derived* copy(Derived* b){...}
};
顺便说一句,访问权限的改变有什么不同吗?比如说,我这样写派生类:
class Derived:public Base{
private://or protected:
virtual Base* copy(Base* b){...}
...
};
最佳答案
这些是函数覆盖的规则:
[C++11: 10.3/2]:
If a virtual member functionvf
is declared in a classBase
and in a classDerived
, derived directly or indirectly fromBase
, a member functionvf
with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (or absence of same) asBase::vf
is declared, thenDerived::vf
is also virtual (whether or not it is so declared) and it overrides111Base::vf
. [..]
如果不满足这些规则,则新函数不会覆盖旧函数(尽管它可能重载或隐藏它) .
所以:
class Base
{
public:
virtual Base* copy(Base* b);
};
class Derived : public Base
{
public:
// Overrides Base::copy
virtual Base* copy(Base* b);
// Does NOT override Base::copy (due to different parameter-type-list)
virtual Base* copy(Derived* b);
// Overrides Base::copy (despite different return type)
virtual Derived* copy(Base* b);
// Does NOT override Base::copy (due to different parameter-type-list)
virtual Derived* copy(Derived* b);
private:
// Overrides Base::copy (despite different access specifier)
virtual Base* copy(Base* b);
};
不过,请注意上面的 Derived
类实际上是错误格式的,因为 10.3/2
的结尾指出:
In a derived class, if a virtual member function of a base class subobject has more than one final overrider the program is ill-formed.
这意味着我们应该只声明那些覆盖函数中的一个。为了说明的目的,我将它们全部列在一个类定义中。
virtual Derived* copy(Base* b)
覆盖 Base::copy
可能令人惊讶,因为它有不同的返回类型;这是允许的,只要两个返回类型是 covariant :
[C++11: 10.3/7]:
The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. If a functionD::f
overrides a functionB::f
, the return types of the functions are covariant if they satisfy the following criteria:
- both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes
- the class in the return type of
B::f
is the same class as the class in the return type ofD::f
, or is an unambiguous and accessible direct or indirect base class of the class in the return type ofD::f
- both pointers or references have the same cv-qualification and the class type in the return type of
D::f
has the same cv-qualification as or less cv-qualification than the class type in the return type ofB::f
.
至于 public
与 private
的问题,没有规则说这很重要;如果有任何疑问,脚注 111 将说明情况:
111 A function with the same name but a different parameter list (Clause 13) as a virtual function is not necessarily virtual and does not override. The use of the
virtual
specifier in the declaration of an overriding function is legal but redundant (has empty semantics). Access control (Clause 11) is not considered in determining overriding.
关于c++ - 关于C++中的虚函数覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18420645/