When to used derived class pointer and base class pointer - c++

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.

Related

Is there a way to bring all definitions in a C++ struct/class into scope without deriving from it?

Musing on a Sunday...
Deriving from a class brings all names from the base class into the scope of the derived class. However, it also adds the base class non-static data members to every instance of the derived class.
Is there a way to achieve the former without the latter? I'm asking in the interest of concise notation.
Obviously, when the base class doesn't have any data members, I get what I want. There are quite a few empty classes or class templates in the standard library defined to do just that - inject names summarily into a class scope through inheritance. There's even the empty base class optimization to make this as cheap as possible.
But if I wanted to do the same with a non-empty base class, I would be tempted to employ something like:
struct Bar {
using struct Foo;
};
But, alas, that's not supported by C++. My question is, is there another way to achieve the same which I overlooked?
To provide a more complete example:
struct Foo {
enum { some_constant=42 };
// data members follow here ...
};
struct Bar {
using class Foo; // this doesn't compile
int f();
};
int Bar::f() {
return some_constant; // I want to use the constant directly, without Foo::
}
One clumsy way could be to split the definitions in Foo into two classes, one with the constants (which would be an empty class I could derive from without penalty) and the other with the data members, but that looks rather like an inelegant hack to me.
If there isn't a clean way to achieve this, maybe someone can provide a rationale for why it doesn't exist, or perhaps shouldn't exist.
Deriving from a class brings all names from the base class into the scope of the derived class.
Let me stop you there. Yes, it is true that inheriting from a base class causes the (non-private) names in the base class to be accessible from the derived class definition. However, that's not why you inherit from a base class; that's merely the mechanism by which inheritance achieves its goal.
To publicly inherit from a base class is to make a statement about the relationship between the derived and base classes. You're saying that every instance of the derived class should behave like the base class in virtually all ways. Even virtual function overriding still carries with it the expectation that the derived class implementations of these methods are conceptually doing the same job, just in a way appropriate for that derived class.
This is true even of mixin-style base classes, where the base class is used to define common functionality that is imported into a particular derived class. In such interfaces, there is little expectation of a user explicitly talking to base class definitions. But this provision of common functionality is ultimately still based on the semantic idea of a derived class being a base class. And that's very important for many of them to do their job.
Consider what is probably the most prominent mixin in the C++ standard library: std::enable_shared_from_this<T>. It has non-static data members, without which it couldn't actually provide the functionality it does (well, it could, but you would have to provide some interface in your derived class to store them, so it may as well do it).
This is true of private inheritance, though there is some modification. While to the outside world, the derived class is just a derived class, to the class definition itself, it still remains a base class. It remains wholly a base class, along with all the baggage that comes along with it.
Do not mistake the mechanism for the meaning. Mechanisms are important; don't get me wrong. But those mechanisms exist to facilitate meaning.
Having a class contain everything of some other class except the non-static data members is, semantically, nonsense. It doesn't mean anything about the relationship between the types. And you've essentially admitted that the main reason you want this is so that you don't have to scope-qualify the names defined in the "base" class.
This is a mechanical reason, not a semantic one. You shouldn't employ a semantic tool like inheritance to escape the mechanical consequences of how you have chosen to design your types.
In reference to your specific example you could make the constants you want to access static, which will allow you to access them from the second class by fully qualifying with the "base" class

Inheritance vs Composition:: Is my understanding correct?

In composition, one class explicitly contains the other. However in Inheritance, the base class is implicitly contained in the derived class. Correct or not? I ask this because after several days of studying inheritance, it's only today that I got to read somewhere that an object of a derived class always contains an object of it's base class.
I mean, I thought that there would be only one object and just the functionality would be inherited but I didn't know that it would also contain an object of the base class within.
In Composition, one object contained another object. While in inheritance, your object is acquire properties of base class.
I mean, I thought that there would be only one object and just the
functionality would be inherited but I didn't know that it would also
contain an object of the base class within.
Yes you are right, there will be only one object and functionality is getting inherited. Even if your base class have member variables, there size will getting added to your object size.
You can directly call public and protected methods of base class. While in cointainership you are only able to access public methods.
That's should be:
In composition, one class explicitly contains an object of the other class. However in Inheritance, the base class is implicitly contained in the derived class.
In short:
Composition is about the relationship of class and object.
Inheritance is about the relationship of class and class.
And please remember "Prefer composition over inheritance".
Prefer composition over inheritance?
In general derived class contains all data members and shares the properties/methods of base class, but there is a difference between composition and inheritance.
By "composition" you mean that one object "has" some other object. In example: human has a liver. In class design it can be presented like below:
class Liver {};
class Human
{
public:
Human() {}
private:
Liver mLiver;
}
When talking about an inheritance, there are 2 options: public inheritance roughly says that one object "is" a kind of other object. In example: Human is a kind of living creature. It does not sound naturally to say that human "has" a living creature inside. Public inheritance is a way to go in such case:
class LivingCreature {};
class Human : public LivingCreature
{
public:
Human() {}
}
Other option is protected/private inheritance, which should be used to implement some object "in terms of" other object. Generally it can also be treated as kind of composition, but first approach is usually better.
Summarizing:
If you can say that one object "is" a kind of other, more general object: public inheritance is the best way to go,
If you can say that one object "has" other object: use composition.
Consider the code:
class Engine
{
//Some Code
};
class Vehicle
{
//Some Code
};
class Car:Vehicle
{
Engine engine;
//Some Code
};
In this case class Car inherits the class Vehicle. An object of the class Car doesn't contain an object Vehicle, rather it is an object of the class Vehicle (Inheritance). On the other hand it does contain an object of the class Engine(Composition).
The fact that you can access a parent's function with this comes from the fact that the Car object is a Vehicle not because it contains an Vehicle object.
In composition, one class explicitly contains the other. However in Inheritance, the base class is implicitly contained in the derived class. Correct or not?
It's entirely a matter of knowledge/perspective: if you're aware that inheritance means a base class instance will be embedded in the derived class then saying class Dervived : Base can be seen as explicitly requesting that, while if you're aware that defining a variable inside class X means it's a member variable that will be contained in instances of X, then that can be seen as explicit too.
I ask this because after several days of studying inheritance, it's only today that I got to read somewhere that an object of a derived class always contains an object of it's [sic] base class.
The distinction between actually containing a base class object vs. through some more unspecified/mysterious means being substitutable for a base class instance on occasion, isn't necessarily the most important thing when starting to learn about inheritance, so it's easy to imagine it isn't emphasised in all learning material.
I mean, I thought that there would be only one object and just the functionality would be inherited but I didn't know that it would also contain an object of the base class within.
At an implementation level, it's important that it actually contains a base class instance, so code compiled to handle base class objects can work equally well on derived class instances. The C++ Standard could have deemed it merely an embedded copy of base class content with identical binary layout while not an actual base class object, but then a huge amount of text in the Standard would have to be added to mention that the derived objects could be used in scenarios where a base class instance was acceptable. In other words, the distinction is somewhat arbitrary, but it's easier for everyone if it's both intuitive and lends itself naturally to simpler, more concise Standard wording.
Inheritance vs Composition:: Is my understanding correct?
Conceptual differences:
Inheritance:
In case of inheritance, derived class is sub-type of base class.
Meaning if you derive Dog from Animal, then Dog is Animal and
all* operations that can be performed on Animal can be performed on Dog.
Using private, protected and public inheritance, however, you can control who knows that Dog is Animal and who knows inner workings of Animal. In case of protected or private inheritance only Dog will know that it is Animal, but it won't be obvious from the outside.
Composition:
In case of composition one class is included into another.
a Car is not a Wheel. But it contains Wheel. So operations that work on Wheel will not work on a Car.
By declaring member variable of type Wheel as public, private or protected you can control who can access Car's Wheels.
I believe that is clear enough?
Implementation details:
In case of C++, members of base class are included into derived class. Also methods that existed in base class will be accessible in derived class - somewhere. Access specifiers private, public and protected AND inheritance type determine which methods are visible and where.
I thought that there would be only one object
It is one object.
In microsoft compiler and g++ objects are "merged" together, meaning that in case of:
struct Base{
int a;
};
strict Derived: public Base{
int b;
};
Derived internally will probably (would need to check C++ standard to be sure) have this layout.
strict Derived{
int a;
int c;
};
or
struct Derived{
Base _;
int c;
};
In case of multiple inheritance and diamond inheritance things will get more complicated and base class can be included multiple times.

Abstract class pointer in C++

The abstract C++ class is a class for which at least one pure virtual method exits.(i.e one can`t instantiate it)
Why and when the pointer to the abstract class should be used?
The only situation I can think about - is classical polymorphic base class pointer which behaves differently based on dispatch table.
Are there any additional reasons?
Upd.
Is class abstract if its constructor is private?
The only situation I can think about - is classical polymorphic base class pointer
Yes, that's exactly what abstract classes are used for, and the only non-bizarre use for them.
Is class abstract if its constructor is private?
No. That class can still be instantiated, but only by its members or friends. An abstract class can't be instantiated at all.
You would use base class pointers to store a collection of disparate objects. Then you could do operations on the items as a group.

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.

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

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.