Main Content

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

Description

Rule Definition

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

Rationale

The checker flags virtual member functions that have multiple definitions on the same path in an inheritance hierarchy. If a function is defined multiple times, it can be ambiguous which implementation is used in a given function call.

Polyspace Implementation

The checker also raises a violation if a base class member function is redefined in the derived class without the virtual keyword.

Troubleshooting

If you expect a rule violation but Polyspace® does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

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()
}

In this example, the virtual function foo is defined in the base class Base and also in the derived class Intermediate1.

A potential source of confusion can be the following. The class Final derives from Intermediate1 and also derives from Base through another path using Intermediate2.

  • When an Intermediate2 object calls the function bar that calls the function foo, the implementation of foo in Base is called. An Intermediate2 object does not know of the implementation in Intermediate1.

  • However, when a Final object calls the same function bar that calls the function foo, the implementation of foo in Intermediate1 is called because of dominance of the more derived class.

You might see unexpected results if you do not take this behavior into account.

To prevent this issue, declare a function as pure virtual in the base class. For instance, you can declare the class Base as follows:

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

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

Check Information

Group: Derived Classes
Category: Required

Version History

Introduced in R2013b