So after searching a lot for an answer to my question, I finally gave up on my Google skills.
I have an base class Base, and a derived class Derived. I want to override a type in the Base class with one in the Derived class. Here's an example:
class Apple {
public:
Apple() { }
// ...
};
class Orange {
public:
Orange() { }
// ...
};
class Base {
public:
typedef Apple fruit;
// ...
virtual fruit func() { return Apple(); }
};
class Derived : public Base {
public:
typedef Orange fruit;
// ...
fruit func() override { return Orange(); } // <-- Error C2555!
};
This code doesn't work, and it gives a
C2555 error ('Derived::func': overriding virtual function return type differs and is not covariant from 'Base::func').
Above was one of solutions I tried. I also tried creating a virtual nested class in the Base, and redefined in Derived, and that didn't compile also (it was also very messy).
I also can't derive Apples and Oranges from the same base class to return pointer/reference to their parent class in Base and Derived. I need to physically return an instance of the object.
You can override (localize) typedef by moving them into the class. But C++ requires virtual functions to have the same signature and the return type is part of the signature.
A redefined function is a method in a descendant class that has a different definition than a non-virtual function in an ancestor class.
Classes and structures can have nested typedefs declared within them.
Overriding: The method in the ancestor class is virtual. A new implementation overrides the virtual one. Redefining: The method in the ancestor class isn't virtual. Therefore the compiler has to choose which method gets used at compiletime.
First of all, look at this syntax :
fruit func() override { return Orange(); }
What is override
? In C++03, there is no such keyword. It's only in C++11. So make sure that you're using a compiler which knows of this keyword.
Second, in the derived class, fruit
is indeed Orange
. Redefining the typedef is not a problem. The problem is, Orange
and Apple
are not covariant type. Deriving one from another will make them covariant. In your case, you've to derive Orange
from Apple
in order to make it work.
Note you've to change the return type from fruit
to either fruit*
or fruit&
.
class Orange : public Apple {}; //correct - your code will work
class Apple : public Orange {}; //incorrect - your code will not work
The idea is, in the base class, the return type should be pointer/reference of base type (which is Apple
), and in the derived class, the return type can be pointer/reference of type Apple
or any class which derives from it.
By the way, does this make sense? Deriving Orange
from Apple
?
How about the following class-design?
class Fruit {};
class Apple : public Fruit {};
class Orange : public Fruit {};
class Base
{
virtual Fruit* f();
};
class Derived : public Base
{
virtual Fruit* f();
};
No need to use typedef
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With