Search code examples
c++principlesooad

technical aspects of 'isa' in c++


what exactly does it mean from technical point of view, I understood that it means that my derived class can always be converted to base class, that's it? I read some materials without any reference to technical aspects, only philosophy! thanks in advance


Solution

  • it means that my derived class can always be converted to base class

    Actually it means better than that. int can always be converted to float, but that doesn't mean an int "is a" float. It just means a float can be constructed from an int. Likewise you can have user-defined classes that convert, but have no other relationship.

    With inheritance, a pointer or reference to the derived class can always be converted to a pointer or reference to the base class[*]. That is to say, an object of the derived class can stand in place of an object of the base class. It actually is one of those things. If a person can stand in for a brain surgeon, then they're a brain surgeon.

    One formal definition if "is a" is Barbara Liskov's substitution principle. Which admittedly is still philosophy, but it's very sound philosophy and it relates directly to how you write programs.

    The other thing you have to keep straight when using inheritance in C++ is the difference between runtime polymorphism (achieved using virtual functions) and static polymorphism (which doesn't actually require inheritance at all). With non-virtual function calls, the version of the function called is always the version defined in the class that the compiler is told the object has (the static type). This might not actually work correctly, if it's overloaded in the derived class. With virtual calls, the version called is the version defined in the class the object actually is (the dynamic type). It's essential to decide which of the two kinds of "is a" you're aiming for.

    [*] and the object be validly accessible through the pointer, that is. You can always coerce pointer types with reinterpret_cast, but that's not what I mean here. And there are some fiddly details - if the base class is ambiguous then you can't convert the pointer in one go, but you can do it explicitly using several unambiguous casts. If the base class is not accessible then you can convert it, but only with a C-style cast, not implicitly. The C-style cast acts like a static_cast which ignores accessibility, not like a reinterpret_class. So you get a working pointer, but hopefully also a strong sense that you're doing something very wrong ;-)