General rule on inheritance

Jan 16, 2022 at 5:55am
Will you please explain this general rule: “a D is a B” does not imply “a
Container<D> is a Container<B>”
with some simple example to be easily understood?
Last edited on Jan 16, 2022 at 5:55am
Jan 16, 2022 at 8:01am
A bus is a vehicle, and a car is a vehicle, but a car is not a bus. A car does not have 12 gears, it doesn't hold 20 passengers, it does not require the same license to drive.
The base class can be called 'vehicle', and 'vehicle' should hold the most basic functions to operate any type of vehicle. Speed is a variable that the 'vehicle' class should maintain, gas increases speed, brakes reduce speed, etc. But the cash earned or the maximum number and count of paying passengers probably should not be maintained by the 'vehicle' class because the 'vehicle' class doesn't know if the inheriting class is a 'bus', a 'taxi', a 'ferrari', or a 'motorcycle', two of which do not generally carry paying passengers.

It seems convenient to store all of your 'vehicle' objects in a vector. You can call any of the 'vehicle' functions on anything in that vector, but it gets interesting if you want to call a 'bus' function on all 'bus' objects in that vector, if you accidentally try to call a 'bus' function like openDoor() on a 'motorcycle' you will run into trouble. Having a separate vector that holds pointers to all those 'bus' objects will start to make more sense. Thus vector <bus *> has different utility from vector <vehicle *> even though a bus is a vehicle.

Polymorphism:
Now, shifting can be declared in the 'vehicle' class, it's common to most 'vehicle' types, but should occur at different times and has different limits per type. If you declare the shift function as virtual, then it can be properly overloaded by inheriting classes, and calling it in the loop will call it from the correct child class type.
Last edited on Jan 16, 2022 at 8:40am
Jan 16, 2022 at 9:06am
The Container is a template. Type Container<D> does not inherit type Container<B>; they are two unrelated types generated from same template.
1
2
3
4
5
6
7
8
void good( B& );
void bad( vector<B>& );

D d;
vector<D> vd;

good( d ); // ok, D is-a B
bad( vd ); // error: vector<D> does not inherit from vector<B> 

Jan 16, 2022 at 12:21pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <iterator>

struct base
{
    int v = 3 ;
};

struct derived : base
{
    double d = 5.6 ;
};

static_assert( sizeof(derived) > sizeof(base) ) ;

int foo( const base* b, std::size_t n )
{
    // b[n-1] is implemented in terms of sizeof(base)
    // it would be disastrous if the sizeof each element of the array != sizeof(base)
    if( b && n > 1 ) return b[n-1].v ;
    else return 0 ;
}

template < std::size_t N > int bar( const base (&b)[N] ) { return foo(b) ; }

int main()
{
    const derived d[23] ;
    foo( d, std::size(d) ) ; // *** unfortunately, this compiles, resulting in general insanity
                             // note: const derived* can be implicitly converted to const base*
                             // moral of the story: don't do this

    // bar(d) ; // *** error *** : no matching function call (this gives an error, as it should)
                // array of derived can't be treated as array of base
}

http://coliru.stacked-crooked.com/a/fd893c05e1551b6b
Jan 18, 2022 at 4:14pm
Thanks for the answers, but still the issue is mystery!
You argue that a derived class/car/bus is a base class/vehicle, but since the vector housing a number of those derived classes and they have distinguished facilities, such a vector is not like a vector of the base class.
It goes without saying that the derived class/bus/car whatever it is, has different facilities in the first place. So how can we say a derived class (D) is a base class (B) but containers of the two aren't alike, while the inconsistencies originally go back to the objects themselves not their containers?
Jan 18, 2022 at 4:18pm
Jan 18, 2022 at 5:32pm
When we say a bus "is a" vehicle, we mean that it has the properties of a vehicle, and the interface of a vehicle. Everything you can do with a vehicle, you can do with a bus.

It can have additional properties and behaviour, unique to buses, but as long as it conforms to the interface of a vehicle, it "is a" vehicle.

In any situation where you have code that operates on a vehicle object, it should be possible to use a bus object, because the bus has the same interface.

This is not true of a vector of buses and a vector of vehicles.
Jan 18, 2022 at 5:38pm
This is not true of a vector of buses and a vector of vehicles.
Why? Is it because a vector/container of buses, too, may have its own properties which can be quite different from a container of vehicles?
Jan 18, 2022 at 5:57pm
Because a vector of buses does not inherit from a vector of vehicles.
Jan 18, 2022 at 7:29pm
Lets write two classes:
1
2
3
4
5
6
7
class BusVector {
  Bus* p;
};

class VehicleVector {
  Vehicle* p;
};

One of them does not inherit the other.

One has busses, the other has vehicles. (HAS-A relationship.)
A Bus might inherit Vehicle, but that does not affect the (non-existent) relationship of the two *Vector classes.

The two classes above end up so similar that we can save effort by making a common template (compile-time polymorphism) and creating them from it:
1
2
3
4
5
6
7
template <typename T>
class Vector {
  T* p;
};

using BusVector = Vector<Bus>;
using VehicleVector = Vector<Vehicle>;

We still get two unrelated classes, even though they share some code.
Last edited on Jan 18, 2022 at 7:30pm
Jan 19, 2022 at 7:21am
Therefore, generally we can say that two classes, bus and vehicle, are two different types, but since the bus class inherits the vehicle class, we can say that a bus is a vehicle, but vectors/containers of those two classes are different types on their own, and since none of them inherits the other, ergo no relationship and we can't say a vector/container of bus is a vector/container of vehicle. Right?
Jan 19, 2022 at 9:07am
Yes.
Jan 19, 2022 at 2:29pm
Thanks for your time. patience, and help. :)
Topic archived. No new replies allowed.