A standard question regarding object oriented design (especially when done in C++ with STL) is why containers don't respect inheritance.

Suppose I have Cars that are Vehicles:

class Vehicle {
  // ...
};
class Car : public Vehicle {
  // ...
};
Then a Car can be converted to a Vehicle, and a pointer to a Car can be converted to a pointer to a Vehicle (no casting necessary).

But if I have a container of Cars, it doesn't inherit from a similar container of Vehicles, and cannot be converted to one under any circumstances! Why? Isn't a list of Cars (list<Car>) a type of a list of Vehicles (list<Vehicle>)?

Suprisingly, the answer is simply NO!

Suppose we implement a one-lane traffic jam as a list of Cars (it's basically a queue). Then I can add Cars to the jam using jam.push_back(c); (where jam is the jam and c is a Car), and I can sometimes remove a car from the jam using c = jam.pop_front(c);.

But suppose I could say list<Vehicle>& unsafe = jam;, or pass jam to a function as a reference parameter unsafe of type list<Vehicle>. Suppose also I had another type Yacht in my program:

class Yacht : public Vehicle {
  // ...
};
Yacht my_yacht;
Then I could say unsafe.push_back(my_yacht); (since Yacht isa Vehicle). Ouch! I'd now have a yacht in a traffic jam -- not type safe behaviour!

For similar reasons, conversion from Car** to Vehicle** is disallowed -- it's just not type safe.

If you really need to do this, you have to define your own adaptor containers which let you perform access in a type safe fashion. And once again, you'll need to use generic programming (not just object oriented programming) in your program if you want any reusability.

Log in or register to write something here or to contact authors.