c ++非虚函数就像虚函数一样

c++ non virtual function acts like virtual function

可能是我误解了c++的多态性(虚函数)。 请指出我想念的。

源代码如下


#include <iostream>

using namespace std;

class A {
    public:
        virtual void print(void) {
            cout<<"class A"<<endl;
        }
};

class B : public A {
    public:
        void print(void) {
            cout<<"class B"<<endl;
        }
};

class C : public B {
    public:
        void print(void) {
            cout<<"class C"<<endl;
        }
};

int main() {
    A a;
    B b;
    C c;
    A *pAa = &a;
    A *pAb = &b;
    A *pAc = &c;
    B *pBc = &c;

    pAa->print();
    pAb->print();
    pAc->print();
    pBc->print();                   // shouldn't be "class B"

    return 0;
}

result

------------------------------
class A
class B
class C
class C                             // shouldn't be "class B"

我的理解是 最后一个打印语句应该打印“class B” 因为 pBc 是 class B 的指针,而 class B 中的打印函数是非虚成员函数。我找不到关于这种情况的答案。

请告诉我原因或指出我在哪里可以找到答案 在理解中理解c++多态性。 谢谢。

the print function in class B is non virtual member function

没有。由于 A::print 被标记为 virtual 并且 B 继承自 A,因此 B::print 也是 virtual;不管键virtual是否被指定。

(强调我的)

If some member function vf is declared as virtual in a class Base, and some class Derived, which is derived, directly or indirectly, from Base, has a declaration for member function with the same

  • name
  • parameter type list (but not the return type)
  • cv-qualifiers
  • ref-qualifiers

Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration).

如果具有给定签名的函数在 top-level 基础 class 中声明为虚函数,则该函数在所有派生的 classes 中都是虚函数 不管是否标示关键字virtual (override, final):

virtual function specifier

Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration)

struct Base {
    // Pure virtual function.
    virtual void foo() const = 0;  
};

struct A : public Base {
    // Overriding virtual function, even if it 
    // is not marked as virtual (override, or final).
    void foo() const {}   
};

A中,给foo()添加virtual说明符只会带来语义值; virtual省略与否在功能上没有区别(除非有人更改了Base中的界面)。


许多静态分析器强制(1) 使用overridefinal 标记派生虚函数,原因有两个:

  • 语义;清楚地表明给定的函数是一个虚函数(根据继承链中更高层的定义),并且
  • 执行;如果一个函数被标记为 overridefinal 但实际上不是 重写函数 ,你将得到一个编译器错误,这对于防止更改基本 class 接口时出错(同时忘记了实际实现此接口的 classes)。

例如:

struct Base {
    // Pure virtual function.
    virtual void foo() const = 0;  
};

struct A : public Base {
    // Overriding virtual function.
    void foo() const override {}   
};

struct B final : public Base {
    // Overriding (final) virtual function.
    void foo() const final {}

    // Error: Function does not override.
    // void bar() const override {}
};

(1) 例如Autsar C++14 Language Guidelines(safety-critical 汽车开发)中的规则 A10-3-1 被归类为必需规则虚函数声明应包含恰好是三个说明符之一:(1) virtual, (2) override, (3) final.