This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 6.4.2 - Derived classes shall not conceal functions that are inherited from their bases
[class.member.lookup]
[namespace.udecl] / 4, 15
Category: Required
Analysis: Decidable,Single Translation Unit
Amplification
A function from a base class is concealed in the derived class if the derived class contains any function or variable with the same name,
unless:
- The base class is inherited privately; or
- The base class function is virtual and the derived class contains an override of it; or
- The base class function is introduced into the derived class through a using-declaration; or
- The base class function is a copy assignment operator or a move assignment operator.
Note: this rule does not apply to constructors or destructors as they do not have names.
Rationale
When performing name lookup, if a function with the requested name exists in the derived class, no lookup will be performed in any base class, even
if the base classes contain functions that would have been better matches. This may result in a call being made to an unexpected function.
Additionally, calling a function directly or through a base class pointer should result in the same function being called, which may not be the
case when a non-virtual base class function is concealed.
Members of a class inherited privately are not accessible outside of the derived class, and so users of the derived type will not encounter the
issues identified above.
Note: a using-declaration will only introduce an overload into a derived class if the derived class does not contain the
same overload — see example for f5.
Example
class Base
{
public:
void f1( int32_t i );
void f2( int32_t i );
virtual Base * f3( char c );
void f4( char c );
void f5( int32_t i );
void f5( char c );
};
class Derived: public Base
{
public:
// Compliant - does not conceal Base::operator=
Derived & operator=( Derived const & ) &;
// Non-compliant - Derived::f1 conceals Base::f1
void f1( float f );
// Compliant - Base::f2 is not concealed
using Base::f2; // Introduces Base::f2( int32_t ) overload
void f2( float f ); // Using declaration means this overload does not conceal
// Compliant - Base::f3 is not concealed
Derived * f3( char const c ) override; // overrides Base::f3( char )
void f3( int32_t i );
// Non-compliant - Base::f4 is concealed
void f4( char c ); // Not an override
void f4( int32_t i );
// Non-compliant - Base::f5( int32_t ) is concealed
using Base::f5; // Introduces Base::f5( char ), not Base::f5( int32_t ) as
void f5( int32_t i ); // this function has the same signature
};
class PrivateDerived: private Base
{
public:
void f1( float f ); // Compliant - Base inherited privately
};
Copyright The MISRA Consortium Limited © 2023