C++ subclass that derives from classes that derive from the same class - c++

Why is the following inheritance structure not legitimate in C++?
Son1 derives from Father1
Son2 derives from Father1
GrandSon1 derives from Son1 and Son2
If there could be a case where this is legitimate (perhaps if all classes are pure-virtual except for GrandSon1), what are they and how come?

You are wrong, this is perfectly legal in C++. You might look into virtual inheritance though.

This inheritance hierarchy is called the diamond of death and it’s legal in C++ if you use virtual inheritance, although it’s usually still problematic.

This is the C++ Diamond Problem.
See: http://en.wikipedia.org/wiki/Diamond_problem

This is the typical inheritance diamond. It occurs even in the standard library where iostream derives from both istream and ostream and both of these derive from ios_base.
There are various issues:
If Father has a virtual method and both Son1 and Son2 implement it, unless Grandson implements it too it has to state which of Son1 and Son2's methods it implements.
If Father has any data members, Grandson would get them twice.
In any case Father has a v-table so you seem to get 2 copies of that.
The middle classes therefore usually use virtual inheritance, which is tricky, but effectively means only the final class gets the base class. So in this case Grandson itself is responsible for constructing Father and is assumed to "have" it.
There are further issues to beware of if you are going to cast any pointers. Particularly be careful with casting to and from a void*.

Me think you are confusing class hierarchy and class instance.
a "grandson" class can derived from a "son" class, but an instance of a "grandson" cannot be from 2 instances of the class "son"
In any cases, I think you should not do it like that because at some point you will have a class "grand-grandson" and a class "grand-grand-grandson".
Make the relation ship between parents and siblings in another way.

Related

Example for non-virtual multiple inheritance

Is there a real-world example where non-virtual multiple inheritance is being used? I'd like to have one mostly for didactic reasons. Slapping around classes named A, B, C, and D, where B and C inherit from A and D inherits from B and C is perfectly fine for explaining the question "Does/Should a D object have one or two A sub-objects?", but bears no weight about why we even have both options. Many examples care about why we do want virtual inheritance, but why would we not want virtual inheritance?
I know what virtual base classes are and how to express that stuff in code. I know about diamond inheritance and examples of multiple inheritance with a virtual base class are abundant.
The best I could find is vehicles. The base class is Vehicle which is inherited by Car and Boat. Among other things, a Vehicle has occupants() and a max_speed(). So an Amphibian that inherits from both Car and Boat inherits different max_speed() on land and water – and that makes sense –, but also different occupants() – and that does not make sense. So the Vehicle sub-objects aren't really independent; that is another problem which might be interesting to solve, but this is not the question.
Is there an example, that makes sense as a real-world model, where the two sub-objects are really independent?
You're thinking like an OOP programmer, trying to design abstract models of things. C++ multiple inheritance, like many things in C++, is a tool that has a particular effect. Whether it maps onto some OOP model is irrelevant next to the utility of the tool itself. To put it another way, you don't need a "real-world model" to justify non-virtual inheritance; you just need a real-world use case.
Because a derived class inherits the members of a base class, inheritance often is used in C++ as a means of collecting a set of common functionality together, sometimes with minimal interaction from the derived class, and injecting this functionality directly into the derived class.
The Curiously Recurring Template Pattern and other mixin-like constructs are mechanisms for doing this. The idea is that you have a base class that is a template, and its template parameter is the derived class that uses it. This allows the base class to have some access to the derived class itself without virtual functions.
The simplest example I can think of in C++ is enable_shared_from_this, which allows an object whose lifetime is currently managed by a shared_ptr to actually retrieve a shared_ptr to that object just from a pointer/reference to that object. That uses CRTP to add the various members and interfaces needed to make shared_from_this possible to the derived class. And since the inheritance is public, it also allows shared_ptr's various functions that "enable shared_from_this" to to detect that a particular type has the shared_from_this stuff in it and to properly initialize it.
enable_shared_from_this doesn't need virtual inheritance, and indeed would probably not work very well with it.
Now imagine that I have some other CRTP class that injects some other functionality into an object. This functionality has nothing to do with shared_ptr, but it uses CRTP and inheritance.
Well, if I now write some type that wants to inherit from both enable_shared_from_this and this other functionality, well, that works just fine. There is no need for virtual inheritance, and in fact doing so would only make composition that much harder.
Virtual inheritance is not free. It fundamentally changes a bunch of things about how a type relates to its base classes. If you inherit from such a type, your constructors have to initialize any virtual base classes directly. The layout of such a type is very odd and is highly unlikely to be standardized. And various other things. C++ tries not to make programmers pay for functionality they don't use, so if you don't need the special properties of virtual inheritance, you shouldn't be using it.
Its the same reason C++ has non-virtual methods -- because the implementation is simpler and more efficient if you use non-virtual inheritance, so you need to explicitly ask for virtual inheritance if you want it. Since you don't need it if your classes never use multiple inheritance, that is the default.

Is it better to cast a base class to derived class or create a virtual function on the base class?

According to this answer, dynamic_cast'ing a base class to derived class is fine, but he says this shows that there is a fundamental problem with the code logic.
I've looked at other answers and using dynamic_cast is fine since you can check the pointer validity later.
Now in my real problem the derived class has a GetStrBasedOnCP function which is not virtual (only the derived class has it) and I have to access it.
What is better, to create a virtual void GetStrBasedOnCP on the base class and make it virtual on the derived OR, to just cast the base class pointer to derived class?
Oh also notice that this is a unsigned int GetStrBasedOnCP so the base class must also return a value...
There are more than two answers to the "what is better" question, and it all depends on what you are modeling:
If the GetStrBasedOnCP function is logically applicable to the base class, using virtual dispatch is the best approach.
If having the GetStrBasedOnCP function in the base class does not make logical sense, you need to use an approach based on the actual type; you could use dynamic_cast, or
You could implement multiple dispatch, e.g. through a visitor or through a map of dynamic types.
The test for logical applicability is the most important one. If GetStrBasedOnCP function is specific to your subclass, adding it to the base class will create maintenance headaches for developers using and maintaining your code.
Multiple dispatch, on the other hand, gives you a flexible approach that lets you access statically typed objects. For example, implementing visitor pattern in your base class lets you make visitors that process the subclass with GetStrBasedOnCP function differently from other subclasses.
Does it make sense for the base class you have to have the virtual function in it?
If it does not then you should not include the function in the base class. Remember that best practices cover the general case. There are times you need to do things you wouldn't normally do to get the code working. The key thing is you need is clear, concise, understandable code
There's a lot of "it depends".
If you can guarantee that the base pointer is the correct child pointer, then you can use dynamic_cast.
If you can't guarantee which child type the base pointer is pointing to, you may want to place the function in the base class.
However, be aware that all children of the base class will get the functionality of whatever you place into the base class. Does it make sense for all the children to have the functionality?
You may want to review your design.

What are the disadvantages of "upcasting"?

The purpose of an abstract class is not to let the developers create an object of the base class and then upcast it, AFAIK.
Now, even if the upcasting is not required, and I still use it, does it prove to be "disadvantageous" in some way?
More clarification:
From The Thinking in C++:
Often in a design, you want the base class to present only an
interface for its derived classes. That is, you don’t want anyone to
actually create an object of the base class, only to upcast to it so that
its interface can be used. This is accomplished by making that class
abstract,
By upcasting, I meant: baseClass *obj = new derived ();
Upcasting can be disadvantageous for non polymorphic classes. For example:
class Fruit { ... }; // doesn't contain any virtual method
class Apple : public Fruit { ... };
class Blackberry : public Fruit { ... };
upcast it somewhere,
Fruit *p = new Apple; // oops, information gone
Now, you will never know (without any manual mechanism) that if *p is an instance of an Apple or a Blackberry.
[Note that dynamic_cast<> is not allowed for non-polymorphic classes.]
Abstract classes are used to express concepts that are common to a set of (sub-)classes, but for which it is not sensible to create instances.
Consider a class Animal. It does not make sense to create an instance of that class, because there is no thing that is just an animal. There are ducks, dogs and elephants, each of which is a subclass of animal. By formally declaring the class animal you can capture the similarities of all types of animals, and by making it abstract you can express that it cannot be instantiated.
Upcasting is required to make use of polymorphism in statically typed languages. This is, as #Jigar Joshi pointed out in a comment, called the Liskov Substituion Principle.
Edit: Upcasting is not disadvantageous. In fact, you should use it whenever possible, making your code depend on super-classes(interfaces) instead of base-classes(implementations). This enables you later switch implementations without having to change your code.
Upcasting is a technical tool.
Like every tool it is useful when used correctly and dangerous / disadvantageous if used inconsistently.
It can be good or bad depending on how "pure" you want your code to be in respect to a given programming paradigm.
Now, C++ is not necessarily "pure OOP", not necessarily "pure Generic", not necessarily "pure functional". And since C++ is a "pragmatic language", it is not in general an advantage force it to fit a "one and only paradigm".
The only thing that can be said, in technical terms, is that,
A derived class is a base class plus something more
Referring a derived through a base pointer makes that "something more" not accessible, unless there is a mechanism in the base to make you jump into the derived scope.
The mechanism C++ offers for that implicit jump are virtual functions.
The mechanism C++ offers for explicit jump is dynamic_cast (used in downcasting).
For non-polymorphic objects (that don't have any virtual method) static_cast (to downcast) is still available, but with no runtime check.
Advantages and disadvantages derive from consistent and inconsistent use of all of those points together. Is not a matter related to downcast only.
One disadvantage would be the obvious loss of new functionality introduced in the derived class:
class A
{
void foo();
}
class B : public A
{
void foo2();
}
A* b = new B;
b->foo2(); //error - no longer visible
I'm talking here about non-virtual functions.
Also, if you forget to make your destructors virtual, you might get some memory leaks when deleting a derived object via a pointer to a base object.
However all these can be avoided with a good architecture.

When to used derived class pointer and base class pointer

Can anyone help me, when i have to used base class and dervied class pointer.
It depends on why you're deriving. If it is for an OO implementation,
most of the time, you'll use pointers to the base class (which will
often by abstract) exclusively; you'll only use pointers to the derived
class if the derived class defines an extended interface. But
inheritance in C++ is a technique, and it is often used for other
purposes. (Think of an iterator class, which inherits from an
instantiation of std::iterator. This is not OO derivation, and
you'ld never use a pointer the the instance of std::iterator.)
I'll often make the distinction, using "derivation" for the OO concept,
and "inheritance" for the C++ technique. But this is in no way
standard, and terminology varies greatly, so you'll usually have to
start by figuring out what the author is talking about: OO design or C++
implementation. And you'll sometimes end up realizing that he doesn't
know himself; that he's confusing the two in his own mind. Inheritance
is the C++ language construct used to implement OO derivation, but this
language construct can be used for other things.
When you have more than one derived classes. and you don't know at compile time that which derived class will be instantiated at runtime. base class pointer is preferred over derived class pointer.
Use the derived class pointer when you want to use the derived class interface, or when you want to ensure that you're dealing with this particular implementation of the base class, or when you want to call a non-virtual function defined in the derived class.
In other circumstances, it doesn't matter.
Base class pointers are used when you have multiple derived classes but you want to abstract yourself from the derived class type. This can be very useful for example in situations like this:
class Animal {
Animal();
}
class Dog : public Animal {
Dog();
}
class Cat : public Animal {
Cat();
}
As you see, in this example you have a base class (Animal) and two derived classes (Cat and Dog). Lets say now that you're running a zoo (that only has Cats and Dogs :) ), and you need to keep up a list of your animals. You could just create two separate lists, one for Cats and another for Dogs. However, if you consider that Cats and Dogs are just Animals, you could create a list with pointers to Animals.
This way, by abstracting yourself from the derived class type, you can work with different derived classes by having a simple pointer to a base class.
Derived class pointers are completely different since they can only "represent" the derived class type.

Proper inheritance

What is meant by proper inheritance?
This thread gives a nice summary:
Proper inheritance occurs when the derived class "IS A" specialized type of the base class. Example Cat IS A Animal.
Improper inheritance occurs when a class is inherited from merely for code reuse without having any other relationship. Example Cat Inherits from Engine. A Cat is not an engine however both an engine and a cat purr.
I would like to add to what Justin and Baxter said.
The term proper inheritance is not really well-defined. Properly using inheritance is quite a subjective issue...
Consider the following example:
An interface: Bird
A concrete class: Ostrich
Should Ostrich inherits from Bird ? From a zoological point of view it makes sense, but from a Computer Science point of view... not so much. If Bird has a fly method, then how am I supposed to handle this in Ostrich::fly :x ?
There is somewhat of a war in the CS community. Indeed you'll regularly see books where Circle inherits from Ellipse (or the other way around) when it doesn't really makes sense from a CS point of view.
So my own little definition:
Considering that the interface defines precise semantics for each of its methods, a concrete class should only inherit from the interface if the implementation of each of the method matches the semantics specified.
Perhaps first we should recall what the value of inheritance itself is. Inheritance is a mechanism for both code reuse and interface reuse (polymorphism). But you can have code reuse without inheritance by using composition and delegation. And in many languages you can have polymorphism without inheritance, but not all languages. In a strongly typed language such as C++, polymorphism, which is itself another important code reuse mechanism, can only be achieved using inheritance. In fact, C++ distinguishes between public and private inheritance for interface and code reuse respectively. More on this later.
Generally one thinks of a class's methods as creating a contract with clients of the class: It guarantees that as long as you call a method having met certain preconditions, the method will deliver certain results. "Proper" inheritance is such that the subclass instance can be substituted for its parent class without violating the parent's contract. That is, none of the subclass's methods should override its base class's methods requiring stricter preconditions nor delivering more "less" results. Returning to C++, since there is a clear distinction between public and private inheritance where the former is required so that you may substitute a subclass instance for a base class instance, it is generally considered "proper" that the substitution be semantically correct. Otherwise why not use private inheritance?
Is Ostrich a valid subclass of Bird? It depends on what your abstraction of Bird is? If the Bird class has a method Bird::fly that does something tangible but Ostrich::fly overrides this to throw an exception and thus delivers "less" than its base class, I would say no. But if class Bird did not have a fly method (there is another subclass Flying_Bird that does), no problem.
My answer is that what holds for C++ is not a bad guideline for any object-oriented language. In a languages like Python where an inheritance hierarchy is not required for polymorphism, people might have a greater tendency to use inheritance just for code reuse. If this reuse is well-documented, it might not be an issue. But when I see a class hierarchy, my expectation is that a subclass is potentially going to be used polymorphically and thus an instance of the subclass can be substituted for an instance of the base class thereby obeyeing the Liskov substitution principle where a subclass is also a subtype.
When inheritance complies with a IS A relationship, as opposed to inheriting purely for code reuse without there being a logical subsumption of the child by the superclass.