Function with same name but different signature in derived class
Functions in derived classes which don't override functions in base classes but which have the same name will hide other functions of the same name in the base class.
It is generally considered bad practice to have have functions in derived classes which have the same name as functions in the bass class which aren't intended to override the base class functions as what you are seeing is not usually desirable behaviour. It is usually preferable to give different functions different names.
If you need to call the base function you will need to scope the call by using A::foo(s)
. Note that this would also disable any virtual function mechanism for A::foo(string)
at the same time.
Overloading virtual method in derived class with different signature
print
in the DERIVED
shadows print
in the BASE
, even though the signatures are different.
To fix, add using BASE::print;
to the DERIVED
. Note that this line can change the access modifier of the inherited function; if you want the function to be public
, the using ...
must also be public
.
Be aware that you don't override any functions here (usually that's only possible if signatures are same). You create two unrelated functions with the same name. This means virtual
can be removed, unless you plan to add more derived classes and actually override functions in them.
Non-virtual function in the base class with same name but different signature not found
When you define a function in a derived class, the overload set with the same name as that function in the base class gets hidden in the derived class. So the compiler only finds the foo
taking an int
in the derived class, which causes an error.
If you want to bring the overload set of foo
from the base class into the derived class, you can use a using
declaration like this:
struct B : public A
{
using A::foo;
// ...
};
Here's a demo.
Derived class doesn't override a virtual function with a different signature
These function signatures are not identical:
virtual int func(double x) {...} // base class
int func(short x) {...} // derived class
One uses double
parameter, the other uses short
. For overriding to occur several conditions must be met. Identical parameter types of the base and derived functions being one of them. Bellow is the excerpt from the "Modern Effective C++" book by Scott Meyers on all the requirements:
• The base class function must be virtual.
• The base and derived
function names must be identical (except in the case of destructors).• The parameter types of the base and derived functions must be
identical.• The constness of the base and derived functions must be
identical.• The return types and exception specifications of the base
and derived functions must be compatible.
Alternatively, make the signatures the same and perform the casting inside a derived function body:
int func(double x) override {
short temp = static_cast<short>(x);
// ...
}
Observation (check): same member function name, different signature, one as virtual member
You may use virtual and non -virtual functions with the same name in base and derived classes.
In the example of classes in your question the definition of the virtual function s in the derived class B hides the non-virtual function with the same name declared in the base class A.
string s() override {
return string("Class B"); // just some string
}
To make it visible in the scope of the derived class you can use the using declaration.
Here is a demonstration program.
#include <iostream>
#include <string>
int main()
{
struct A
{
std::string f( int i ) const
{
return f() + '(' + std::to_string( i ) + ')';
}
virtual std::string f() const
{
return "struct A";
}
virtual ~A() = default;
};
struct B : A
{
using A::f;
virtual std::string f() const override
{
return "struct B";
}
};
B b;
std::cout << b.f( 1 ) << '\n';
A &rb = b;
std::cout << rb.f( 2 ) << '\n';
A a;
std::cout << a.f( 3 ) << '\n';
}
The program output is
struct B(1)
struct B(2)
struct A(3)
Related Topics
What Is the Curiously Recurring Template Pattern (Crtp)
Single Quotes Vs. Double Quotes in C or C++
C++ Returning Reference to Local Variable
What Are the Main Purposes of Using Std::Forward and Which Problems It Solves
How to Enable C++11/C++0X Support in Eclipse Cdt
How to Reverse a String in Place in C or C++
In Which Scenario Do I Use a Particular Stl Container
Passing Capturing Lambda as Function Pointer
What Is a "Translation Unit" in C++
Why Does Dividing Two Int Not Yield the Right Value When Assigned to Double
What's the Correct Way to Use Printf to Print a Size_T
Erasing Elements from a Vector
How to Parse a String to an Int in C++
Store Hex Value as String (Arduino Project)
Explicit Template Instantiation - When Is It Used
How to Get a Stack Trace for C++ Using Gcc With Line Number Information