The 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.


== Noncompliant Code Example

----
class 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 ( ) { } // Noncompliant: 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 ( ) { } // Noncompliant 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 ( ) { } // Noncompliant 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 ( ) { } // Noncompliant
};

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"
----


== See

* MISRA {cpp}:2008, 10-3-1 - There shall be no more than one definition of each virtual function on each path through the inheritance hierarchy.


ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)

include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]
