I have been taught in my C++ OOP class about polymorphism that how we can provide virtual function interfaces to derived classes. But the question is how all this can help? Every time we make a base class pointer and store a derived class object in it, But why? Can't we do it just by function overriding.
Please Tell a programming problem which cannot be solved except with polymorphism in C++
Virtual functions and overriding vs. non-virtual functions and name hiding
Virtual functions make a class polymorphic. A virtual function can be overriden in derived classes. When you invoke that function through a base class pointer, it's always the function corresponding to the real dynamic type of the poined object that will be called. It's dynamic determination at run-time.
Non-virtual functions can't be overriden. When a derived class has a non-virtual function with the same signature than the base class, it's two different functions but the name of the derived class hides the one of the base class. When you invoke the function through a base class pointer, it's allways the function corresponding to the base class which will be invoked. It's static determination at compile-time.
What's the benefit ? do we need virtual functions ?
Virtual functions are just an easy way to define abstraction. The typical example are shapes. You define an abstract shape, with a virtual functions such as calculateSurface(). You then can call that function via any pointer and you'll be sure that for any concrete shape (e.g. circle, square, hexagon...) it will always apply the right formula for the object.
Abstraction is convenient. But you could live without it. For example, you could as well implement the same functionality, by using a shape code, and having a a calculateSurface() that would execute the right formula depending on the shape code. It's perfectly possible. It's just more difficult to maintain, because everytime you create a new shape, you'd need to ad another if (shapeCode==xx) clause in all the places where the behavior is dependent of the shape.
In fact you don't even need an OOP. In former times, before c++ existed, it was a common programming technique to use function pointers in C to emulate such a type dependent behavior (using a struct that contained a function pointer for every type dependent operation). Again, it's perfectly feasible, but even more tedious and more error prone and less encapsulated.
So, there is no problel that would require polymorphism to be solved. There are just plenty of problems where OOP and polymorphism makes the problem easier to solve, with more maintainable code.
Related
why we need interface ( pure virtual function or abstract class) in c++?
Instead of having abstract class, Can we have a base class with virtual function defined in it, and override that virtual function in derived class.
what would be the advantage and disadvantage with the above approach ( except we can create the object of the base class)?
Pure virtual functions are for when there's no sensible way to implement the function in the base class. For example:
class Shape {
public:
virtual float area() const = 0;
};
You can write derived classes like Circle and Rectangle that implement area() using the specific formulas for those kinds of shapes. But how would you implement area() in Shape itself, if it weren't pure virtual? How do you compute the area of a shape without even knowing what kind of shape it is?
If your function can be implemented (in a useful way) in the base class, then go ahead and implement it. Not all base classes need to be abstract. But some of them just inherently are abstract, like Shape.
Pure virtual functions is your way of telling the users of your class that they cannot use the class on its own, without inheriting from it.
Obviously, you can do what you describe, and the system is going to compile and work as expected. However, an pure virtual function is not a construct for the compiler; it is for humans who read your code. It is with this construct that you tell the readers of your code that they must inherit from your class, because the class is not designed to be instantiated on its own.
You use pure virtual functions in situations when there is no reasonable default implementation for a function. This tells people who implement your class that they must provide certain functionality, and the compiler helps them in detecting situations when they forgot to provide an implementation.
If, on the other hand, you provide a default implementation for a virtual function that should be implemented by a subclass, and then the users of your class library forget to provide an implementation, the problem would not be detected until run-time.
An interface give you the ability to specify a set of behaviors that
all classes that implement the interface will share in common.
Consequently, we can define variables and collections (such as arrays)
that don't have to know in advance what kind of specific object they
will hold, only that they'll hold objects that implement the
interface.
Here
As others have said, an interface is a contractual obligation to implement certain methods, properties and events [...] That's a sufficiently awesome benefit to justify the feature.
and here
(please refer to these very good explanations)
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.
Because of C++ nature of static-binding for methods, this affects the polymorphic calls.
From Wikipedia:
Although the overhead involved in this dispatch mechanism is low, it
may still be significant for some application areas that the language
was designed to target. For this reason, Bjarne Stroustrup, the
designer of C++, elected to make dynamic dispatch optional and
non-default. Only functions declared with the virtual keyword will be
dispatched based on the runtime type of the object; other functions
will be dispatched based on the object's static type.
So the code:
Polygon* p = new Triangle;
p->area();
provided that area() is a non-virtual function in Parent class that is overridden in the Child class, the code above will call the Parent's class method which might not be expected by the developer. (thanks to the static-binding I've introduced)
So, If I want to write a class to be used by others (e.g library), should I make all my functions to be virtual for the such previous code to run as expected?
The simple answer is if you intend functions of your class to be overridden for runtime polymorphism you should mark them as virtual, and not if you don't intend so.
Don't mark your functions virtual just because you feel it imparts additional flexibility, rather think of your design and purpose of exposing an interface. For ex: If your class is not designed to be inherited then making your member functions virtual will be misleading. A good example of this is Standard Library containers,which are not meant to be inherited and hence they do not have virtual destructors.
There are n no of reasons why not to mark all your member functions virtual, to quote some performance penalties, non-POD class type and so on, but if you really intent that your class is intended for run time overidding then that is the purpose of it and its about and over the so-called deficiencies.
Mark it virtual if derived classes should be able to override that method. It's as simple as that.
In terms of memory performance, you get a virtual pointer table if anything is virtual, so one way to look at it is "please one, please all". Otherwise, as the others say, mark them as virtual if you want them to be overridable such that calling that method on a base class means that the specialized versions are run.
As a general rule, you should only mark a function virtual if the class is explicitly designed to be used as a base class, and that function is designed to be overridden. In practice, most virtual functions will be pure virtual in the base class. And except in cases of call inversion, where you explicitly don't provide a contract for the overriding function, virtual functions should be private (or at the most protected), and wrapped with non-virtual functions enforcing the contract.
That's basically the idea ; actually if you are using a parent class, I don't think you'll need to override every methods so just make them virtual if you think you'll use it this way.
Consider a scenario where there are two classes i.e. Base and Derived. If the Base class wants to call a function of the derived class, it can do so by either making a virtual function and defining that VF in the derived class or by using callbacks. I want to know in what should be preferred out of the two? Choosing among the two depends on which situations/conditions?
EDIT:
Question Clarification:
The situation I was referring to is that there is a base class which receives messages. These different messages are to be handled differently by the derived class, so one way is to create a virtual function and let the derived class implement it, handling every message though various switch cases.
Another way is to implement the callbacks through the function pointers (pointing to the functions of derived class) inside the templates (templates are needed for handling the object of the derived class and the function names). The templates and the function pointers are going to reside in the base class.
A virtual function call is actually a callback.
The caller looks up the corresponding entry in the object's virtual function table and calls it. That's exactly like a callback behaves, except that member function pointers have awkward syntax. Virtual functions offload the work to the compiler, which makes them a very elegant solution.
Virtual functions are the way to communicate within the inheritance hierarchy.
I think this comes down to a decision about whether or not the behaviour you're talking about is something that belongs in the heirarchy that 'Base' knows about and child implements.
If you go with a callback solution, then the callback method (depending on signature) doesn't have to be implemented in a child of Base. This may be appropriate if for example you wanted to say 'this event has happened' to an 'event listener' that could be in a derived class, or could be in a totally unrelated class that happens to be interested in the event.
If you go with the virtual function solution, then you're more tightly coupling the implentation of the Derived and Base classes.
An interesting read, which may go some way to answering your question is: Callbacks in C++ which talks about the usage of Functors. There's also an example on Wikipedia that uses a template callback for sorting. You'll notice that the implementation for the callback (which is a comparison function) does not have to be in the object that is performing the sort. If it were implemented using virtual methods, this wouldn't be the case.
I don't think that the two cases you are describing are comparable. Virtual functions are a polymorphism tool that aid you in extending a base class in order to provide additional functionality. The key characteristic of them is that the decision which function will be called is made in runtime.
Callbacks are a more general concept, that doesn't apply only on a Parent-Child class relationship.
So, if you want to do involves extending a base class, I would certainly go with virtual functions. Be sure however to understand how virtual functions work.
I know it is not allowed in C++, but why? What if it was allowed, what would the problems be?
Judging by your other question, it seems you don't understand how classes operate. Classes are a collection of functions which operate on data.
Functions themselves contain no memory in a class. The following class:
struct dumb_class
{
void foo(){}
void bar(){}
void baz(){}
// .. for all eternity
int i;
};
Has a size of int. No matter how many functions you have ever, this class will only take up the space it takes to operate on an int. When you call a function in this class, the compiler will pass you a pointer to the place where the data in the class is stored; this is the this pointer.
So, the function lie in memory somewhere, loaded once at the beginning of your program, and wait to be called with data to operate on.
Virtual functions are different. The C++ standard does not mandate how the behavior of the virtual functions should go about, only what that behavior should be. Typically, implementations use what's called a virtual table, or vtable for short. A vtable is a table of function pointers, which like normal functions, only get allocated once.
Take this class, and assume our implementor uses vtables:
struct base { virtual void foo(void); };
struct derived { virtual void foo(void); };
The compiler will need to make two vtables, one for base and one for derived. They will look something like this:
typedef /* some generic function pointer type */ func_ptr;
func_ptr __baseTable[] = {&base::foo};
func_ptr __derivedTable[] = {&derived::foo};
How does it use this table? When you create an instance of a class above, the compiler slips in a hidden pointer, which will point to the correct vtable. So when you say:
derived d;
base* b = &d;
b->foo();
Upon executing the last line, it goes to the correct table (__derivedTable in this case), goes to the correct index (0 in this case), and calls that function. As you can see, that will end up calling derived::foo, which is exactly what should happen.
Note, for later, this is the same as doing derived::foo(b), passing b as the this pointer.
So, when virtual methods are present, the class of the size will increase by one pointer (the pointer to the vtable.) Multiple inheritance changes this a bit, but it's mostly the same. You can get more details at C++-FAQ.
Now, to your question. I have:
struct base { virtual void foo(void) = 0; }; // notice the = 0
struct derived { virtual void foo(void); };
and base::foo has no implementation. This makes base::foo a pure abstract function. So, if I were to call it, like above:
derived d;
base* b = &d;
base::foo(b);
What behavior should we expect? Being a pure virtual method, base::foo doesn't even exist. The above code is undefined behavior, and could do anything from nothing to crashing, with anything in between. (Or worse.)
Think about what a pure abstract function represents. Remember, functions take no data, they only describe how to manipulate data. A pure abstract function says: "I want to call this method and have my data be manipulated. How you do this is up to you."
So when you say, "Well, let's call an abstract method", you're replying to the above with: "Up to me? No, you do it." to which it will reply "##^##^". It simply doesn't make sense to tell someone who's saying "do this", "no."
To answer your question directly:
"why we cannot create an object for an abstract class?"
Hopefully you see now, abstract classes only define the functionality the concrete class should be able to do. The abstract class itself is only a blue-print; you don't live in blue-prints, you live in houses that implement the blue-prints.
The problem is simply this:
what should the program do when an abstract method is called?
and even worse: what should be returned for a non-void function?
The application whould proabably have to crash or thow a runtime exception and thus this would cause trouble. You can't dummy-implement every abstract function.
A class can simply be declared abstract where it has no abstract methods. I guess that could be instantiated in theory but the class designer doesn't want you to. It may have unintended consequences.
Usually however abstract classes have abstract methods. They can't be instantiated for the simple reason that they're missing those methods.
Because logically it does not make any sense.
An abstract class is a description that is incomplete.
It indicates what things need to be filled out to make it complete but without those bits its not complete.
My first example was a chess game:
The game has lots of pieces of different type (King,Queen,Pawn ... etc).
But there are no actual objects of type piece, but all objects are instances of objects derived from piece. How can you have an object of something that is not fully defined. There is not point in creating an object of piece as the game does not know how it moves (that is the abstract part). It knows it can move but not how it does it.
Abstract classes are non-instantiable by definition. They require that there be derived, concrete classes. What else would an abstract class be if it didn't have pure virtual (unimplemented) functions?
It's the same class of question as why can't I change the value of a const variable, why can't I access private class members from other classes or why can't I override final methods.
Because that's the purpose of these keywords, to prevent you from doing so. Because the author of the code deemed doing so dangerous, undesired or simply impossible due to some abstract reasons like lack of essential functions that need to be added by specific child classes. It isn't really that you can't instantiate because a class is virtual. It's that inability to instantiate a class defines it as virtual (and if a class that can't be instantiated isn't virtual, it's an error. Same goes the other way, if instance of given class makes sense, it shouldn't be marked as virtual)
Why we cant create an object of an abstract class?
simply abstract class contains abstract methods(means the functions which are without the body) and we cannot give functionality to the abstract methods. And if we try to give functionality to the abstract methods then there will be no difference between abstract class and virtual class. So lastly if we create an object Of an abstrast class then there is no fun to call the useless functions or abstract methods as they are without the functionality..so thats why any language doesnt allow us to create an object of an abstract class..
Abstract classes instantiated would be pretty useless, because you would be seeing a lot more of "pure virtual function called". :)
It's like: we all know that a car would have 3 pedals and a steering wheel and a gear stick. Now, if that would be it, and there'd be an instance of 3 pedals and gear stick and a wheel, I'm not buying it, I want a car, like with seats, doors, AC etc. with pedals actually doing something apart from being in existence and that's what abstract class doesn't promise me, the ones implementing it do.
Basically creation of object is responsible for allocation of memory for member variables and member functions. but here, in pure virtual function we have declaration and defination in derived class.so creation of object generates error.