For return types Covariance of the return values are required by the Liskov Substitiution Principle.
Lets assume the small type hierarchy for return types:
class B {};
class D : public B {};
The working classes then could have
class Base {
virtual B& func();
};
class Derived : public Base {
virtual D& func();
};
and this would be compliant to the LSP because the return types are covariant (the hierarchy of Base
and Derived
is "co" to B
and D
).
What if containers do come into play?
class Base {
virtual vector<B>& func();
};
class Derived : public Base {
virtual vector<D>& func();
};
Is this still LSP compliant? Are vector<B>
and vector<D>
"covariant" to Base
and Derived
?
Additional question: Does it make a difference for the LSP if I use pointers as container types (allowing for dynamic polymorphism), i.e. vector<B*>
etc?
Note: I tried not to rely on the real C++ override rules but mainly want to understand LSP. I did nor use the override
keyword intentionally. First I want to understand LSP then I could try out if C++ supports these rules.
vector<B>
and vector<D>
are two completely unrelated types, so it is not LSP compliant.
vector<B*>
and vector<D*>
are also two completely unrelated types as far as the C++ type system is concerned. Since B
is a base class of D
, you could just use vector<B*>
for both, and covariance would not then be an issue.