MISRA.BASE.MANYDEFSBoth overriding and overridden virtual functions have definitions. MISRA-C++ Rule 10-3-1 (required): There shall be no more than one definition of each virtual function on each path through the inheritance hierarchy.RationaleThe main aim of this rule is clarity for maintainers and reviewers, by ensuring that the version of a function that can be executed from any point in a class hierarchy is unambiguous. Additionally, where classes form a diamond hierarchy, call by dominance ([1] §10.3(11)) may occur resulting in a call to a function that is inconsistent with developer expectations. This rule also prevents call by dominance. ExceptionDestructors may be declared virtual in multiple members of a class hierarchy. If a function is declared pure and defined in the same class, then that definition is ignored for this rule. Exampleclass A { public: virtual void f1 ( ) = 0; // f1 is pure virtual void f2 ( ) = 0; // f2 is pure virtual void f3 ( ) { } // f3 is not pure virtual void f4 ( ) = 0; // f4 is pure virtual ~A(); // destructor }; // A::f1 is both pure and has a definition void A::f1 ( ) { } // A::f4 is both pure and has a definition void A::f4 ( ) { } class B : public A { public: virtual void f2 ( ) { } // Compliant: f2 pure in A and // defined in B virtual void f3 ( ) { } // Non-compliant: f3 defined in A and B virtual void f4 ( ) = 0; // Compliant: f4 is pure in A and in B virtual ~B(); // Compliant: destructor }; // Compliant by Exception - f4 defined in A but also declared pure in A void B::f4 ( ) { } class C : public B { public: virtual void f1 ( ) { } // Compliant: f1 defined in A and C // but was pure in A virtual void f2 ( ) { } // Non-compliant f2: defined in B and C // and not declared pure in B virtual void f4 ( ) { } // Compliant by Exception: f4 defined in A // and B but also declared pure in A and B }; class D : public C { public: virtual void f1 ( ) { } // Non-compliant f1: defined in C and D // as well as A virtual ~D(); // Compliant: destructor }; // Call by dominance example class V { public: virtual void foo ( ) { } }; class B1 : public virtual V { public: virtual void foo ( ) // Non-compliant { } }; class B2 : public virtual V { public: void f1 ( ) { foo(); // V::foo would appear to be the only // candidate to be called here } }; class D : public B1, public B2 { public: void f2 ( ) { f1(); } }; B2 b2; b2.f1(); // calls V::foo by normal inheritance rules D d; d.f2(); // calls B2::f1 which now calls B1::foo // "by dominance" d.f1(); // also calls B1::foo "by dominance" |