I am trying to understand inheritance and polymorphism. When I run this :
#include<iostream>
using namespace std;
class Base
{
int x;
public:
virtual Base* fun() = 0;
int getX() { return x; }
};
// This class inherits from Base and implements fun()
class Derived: public Base
{
public:
int y;
Derived* fun() {
Derived *d = new Derived;
d->y = 2;
return d;
}
};
int main(void)
{
Derived d;
Derived *p = d.fun();
cout<< p->y;
}
This works fine as it is legal for a derived class to override a virtual function using a different return type as long as the return type is covariant with the original return type
But what if the virtual function contain the input argument of type Base*
. Like :
#include<iostream>
using namespace std;
class Base
{
int x;
public:
virtual Base* fun(Base * t) = 0;
int getX() { return x; }
};
// This class inherits from Base and implements fun()
class Derived: public Base
{
public:
int y;
Derived* fun(Derived *t) {
Derived *d = new Derived;
d->y = t->y;
return d;
}
};
int main(void)
{
Derived d;
Derived *p = d.fun();
cout<< p->y;
}
This is throwing error error: invalid new-expression of abstract class type ‘Derived’ Derived *d = new Derived;
which I understand it means that compiler is not recognising the implementation of the virtual function and considering the class ``Derived``` as abstract.
So how can we override virtual function of this type ?? I tried to search it , but didn't find any reference. If similar question exists , let me know. Thanks
If I needed this in my own code. I'd write the new derived class like this:
// This class inherits from Base and implements fun()
class Derived: public Base
{
public:
int y;
Derived* fun(Base *t) {
Derived *d = new Derived;
Derived* input = dynamic_cast<Derived *>(t);
ASSERT(input); // Cause the debug version to throw an exception so the error can be debugged
if(input)
d->y = t->y;
else
d->y = 0; // Or the default of your choice.
return d;
}
};
This introduces a potential runtime error if the base type passed in is not the correct derived type. But I don't see a way to avoid it.
The other options I see are use templates. Where the derived type requires the derived type to be passed in. Or simply create a new function that takes the derived type as input and also overrides fun(Base *t)
;