c++liskov-substitution-principlecovariantcovariant-return-types

How do C++ containers work together with the Liskov Substitution Principle?


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.


Solution

  • 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.