覆盖虚函数和隐藏非虚函数有什么区别? [英] What are the differences between overriding virtual functions and hiding non-virtual functions?

查看:401
本文介绍了覆盖虚函数和隐藏非虚函数有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下代码片段,函数调用有什么区别?什么是函数隐藏?什么是函数覆盖?它们如何与函数重载相关?两者之间有什么区别?我在一个地方找不到这些描述,所以我要求这里,以便我可以巩固的信息。

Given the following code fragment, what are the differences in the function calls? What is function hiding? What is function overriding? How do they relate to function overloads? What is the difference between the two? I couldn't find a good description of these in one place, so I'm asking here so I can consolidate the information.

class Parent {
  public:
    void doA() { cout << "doA in Parent" << endl; }
    virtual void doB() { cout << "doB in Parent" << endl; }
};

class Child : public Parent {
  public:
    void doA() { cout << "doA in Child" << endl; }
    void doB() { cout << "doB in Child" << endl; }
};

Parent* p1 = new Parent();
Parent* p2 = new Child();
Child* cp = new Child();

void testStuff() {
  p1->doA();
  p2->doA();
  cp->doA();

  p1->doB();
  p2->doB();
  cp->doB();
}


推荐答案

什么是函数隐藏? / h3>

...是一种名称隐藏的形式。一个简单的例子:

What is function hiding?

... is a form of name hiding. A simple example:

void foo(int);
namespace X
{
    void foo();

    void bar()
    {
        foo(42); // will not find `::foo`
        // because `X::foo` hides it
    }
}

这也适用于基类中的名称查找:

This also applies to the name lookup in a base class:

class Base
{
public:
    void foo(int);
};

class Derived : public Base
{
public:
    void foo();
    void bar()
    {
        foo(42); // will not find `Base::foo`
        // because `Derived::foo` hides it
    }
};






什么是函数覆盖?



这与虚拟函数的概念相关联。 [class.virtual] / 2


What is function overriding?

This is linked to the concept of virtual functions. [class.virtual]/2


如果虚拟成员函数 vf Base 中和在 Derived 中直接或间接从 code>,具有相同名称,参数类型列表,cv-qualification和ref-qualifier(或不存在相同)的成员函数 vf code> Base :: vf ,那么 Derived :: vf 也是虚拟的(无论是否声明)它会覆盖 Base :: vf

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, 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 overrides Base::vf.



class Base
{
private:
    virtual void vf(int) const &&;
    virtual void vf2(int);
    virtual Base* vf3(int);
};

class Derived : public Base
{
public: // accessibility doesn't matter!
    void vf(int) const &&; // overrides `Base::vf(int) const &&`
    void vf2(/*int*/);     // does NOT override `Base::vf2`
    Derived* vf3(int);     // DOES override `Base::vf3` (covariant return type)
};

调用虚函数时,最终的覆盖变得相关:[class.virtual] / 2

The final overrider becomes relevant when calling a virtual function: [class.virtual]/2


类对象的一个​​虚拟成员函数 C :: vf 除非 S 的最大派生类是一个基类子对象(如果有的话)声明或继承另一个成员函数覆盖,否则S vf

A virtual member function C::vf of a class object S is a final overrider unless the most derived class of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.

如果你有一个 S 类型的对象,最终的overrider是你在遍历 S 回到其基类。重要的是,使用函数调用表达式的动态类型来确定最终的超越属性:

I.e. if you have an object of type S, the final overrider is the first overrider you see when traversing the class hierarchy of S back to its base classes. The important point is that the dynamic type of the function-call expression is used in order to determine the final overrider:

Base* p = new Derived;
p -> vf();    // dynamic type of `*p` is `Derived`

Base& b = *p;
b  . vf();    // dynamic type of `b` is `Derived`






< h3>覆盖和隐藏之间的区别是什么?

基本上,基类中的函数总是被派生类中相同名称的函数隐藏;不管派生类中的函数是否覆盖基类的虚函数:


What is the difference between overriding and hiding?

Essentially, the functions in the base class are always hidden by functions of the same name in a derived class; no matter if the function in the derived class overrides a base class' virtual function or not:

class Base
{
private:
    virtual void vf(int);
    virtual void vf2(int);
};

class Derived : public Base
{
public:
    void vf();     // doesn't override, but hides `Base::vf(int)`
    void vf2(int); // overrides and hides `Base::vf2(int)`
};

要查找函数名,使用表达式的静态类型:

To find a function name, the static type of an expression is used:

Derived d;
d.vf(42);   // `vf` is found as `Derived::vf()`, this call is ill-formed
            // (too many arguments)






它们如何与函数重载相关联?



Asfunction隐藏是一种名称隐藏的形式,如果函数的名称被隐藏,所有重载都会受到影响:


How do they relate to function overloads?

As "function hiding" is a form of name hiding, all overloads are affected if the name of a function is hidden:

class Base
{
private:
    virtual void vf(int);
    virtual void vf(double);
};

class Derived : public Base
{
public:
    void vf();     // hides `Base::vf(int)` and `Base::vf(double)`
};

对于函数覆盖,只有基类中具有相同参数的函数才会被覆盖;你当然可以重载一个虚函数:

For function overriding, only the function in the base class with the same arguments will be overriden; you can of course overload a virtual function:

class Base
{
private:
    virtual void vf(int);
    virtual void vf(double);
    void vf(char);  // will be hidden by overrides in a derived class
};

class Derived : public Base
{
public:
    void vf(int);    // overrides `Base::vf(int)`
    void vf(double); // overrides `Base::vf(double)`
};

这篇关于覆盖虚函数和隐藏非虚函数有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆