主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

MISRA C++:2008 Rule 10-3-1

There shall be no more than one definition of each virtual function on each path through the inheritance hierarchy

描述

规则定义

There shall be no more than one definition of each virtual function on each path through the inheritance hierarchy. 1

理由

检查项对在继承层次结构中同一路径上具有多个定义的虚拟成员函数进行标记。如果一个函数被多次定义,则在给定函数调用中使用的是哪个实现可能会出现歧义。

Polyspace 实现

如果在派生类中重新定义了基类成员函数,但未使用关键字 virtual,检查项也会引发违规。

故障排除

如果您预期会出现违规,而 Polyspace® 未报告该违规,请参阅诊断为何编码规范违规未按预期显示

示例

全部展开

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

class Intermediate1: public virtual Base {
    public:
      virtual void foo() { //Noncompliant
      }    
};

class Intermediate2: public virtual Base {
    public:
       void bar() {
          foo();  // Calls Base::foo()
      }    
};

class Final: public Intermediate1, public Intermediate2 {
};

void main() {
    Intermediate2 intermediate2Obj;
    intermediate2Obj.bar(); // Calls Base::foo()
    Final finalObj;
    finalObj.bar(); //Calls Intermediate1::foo() 
                    //but you might expect Base::foo()
}

在此示例中,virtual 函数 foo 在基类 Base 和派生类 Intermediate1 中都进行了定义。

一个可能引起混淆的点是以下内容。类 Final 源自 Intermediate1,并通过使用 Intermediate2 的另一条路径源自 Base

  • 当一个 Intermediate2 对象调用调用函数 foo 的函数 bar 时,将调用 Basefoo 的实现。Intermediate2 对象不知道 Intermediate1 中的实现。

  • 但是,当一个 Final 对象调用与调用函数 foo 的函数相同的函数 bar 时,由于更派生类的优先级更高,因此会调用 Intermediate1foo 的实现。

如果您未考虑此行为,可能会看到意外结果。

要防止出现此问题,请在基类中将函数声明为纯虚函数。例如,您可以如下声明类 Base

class Base {
    public:
      virtual void foo()=0;
};

void Base::foo() {
      //You can still define Base::foo()
}

检查信息

组:派生类
类别:必需

版本历史记录

在 R2013b 中推出


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.