c++ - 关于C++中的虚函数覆盖

标签 c++ inheritance polymorphism overriding virtual

我对以下情况有点困惑,它们是覆盖函数 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 function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides111 Base::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 function D::f overrides a function B::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 of D::f, or is an unambiguous and accessible direct or indirect base class of the class in the return type of D::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 of B::f.

至于 publicprivate 的问题,没有规则说这很重要;如果有任何疑问,脚注 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/

相关文章:

C# 为什么不能进行委托(delegate)覆盖?

c++ - 具有虚拟和非虚拟析构函数的 delete 运算符的不同行为

php - 如何给抽象方法的参数添加类名类型?

c++ - 用于访问多态类型的 std::visit-like 函数

c++ - C++虚函数的输出

c++ - 使用指向对象的指针显式调用析构函数

c++ - 需要帮助修复这些类的错误

c++ - 是否有一种内存有效的方法来探索从输入排列生成的解决方案?

c++ - boost::asio 扩展 TCP 套接字

java - 如何使 <T extends E> 包含泛型类型参数?