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
views:
112answers:
2A derived class can be converted to only an accessible and unambiguous base class at a given point R. There is no dearth of references and what other place than the C++ standard itself.
$10.2 is a good reference: A derived class can itself serve as a base class subject to access control; see 11.2. A pointer to a derived class can be implicitly converted to a pointer to an accessible unambiguous base class (4.10). An lvalue of a derived class type can be bound to a reference to an accessible unambiguous base class (8.5.3). —end note ]
And again
$10.3 - "The base-specifier-list specifies the type of the base class subobjects contained in an object of the derived class type.[..] Here, an object of class Derived2 will have a subobject of class Derived which in turn will have a subobject of class Base.[...]
In terms of OOAD principles:
I would personally recommend Robert Martin's articles for getting a good hold on this especially the OCP principle. It is not possible for me to beat the clarity and authority with which the author explains these legendary OOAD guidelines
Also look at LSP as explained in @Steves' post
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 ;-)