Hi.
Is there an advantage to using dynamic binding instead of static binding?
I have both Deitel & Deitel C++ How to Program and Stroustrup's Special Edition. I read all of the first book and finished chapter fifteen of Stroustrup. So I understand virtual functions and virtual base. However, I am not to the point where I can implement virtual functions and virtual base without asking: How do you implement them effectively?
For example, "virtual" only works for pointer and reference. That is completely conceivable. However, it seems you have to declare an object of a derived class and then *cast* a new class from the base class to the derive class just to get it working right.
-----------------
classDerived cDerived = new classDerived;
classBase *cBase = &cDerived;
-----------------
The example above comes straight from Deitel & Deitel. So everything looks okay. What is the point of declaring two separate classes? I understand that the use of "virtual," but I do not understand the performance of "virtual" if you have to declare an object of the derived class and an object of the base class. Under what specific situation do you implement dynamic binding? Please be very specific because I found that neither Deitel & Deitel nor Stroustrup give a convincing example of dynamic binding.
Lastly, I too want to implement dynimic binding if it is possible to declare *one* object of either the base class or the derived class. The following is *not correct*:
------------------------
classBase *cDynamic = new classDerived
------------------------
In other words, *virtual* would be great if there is a way to use it without having to declare two seperate classes like the example from Deitel & Deitel.
Thanks,
Kuphryn
Comments
: I have both Deitel & Deitel C++ How to Program and Stroustrup's Special Edition. I read all of the first book and finished chapter fifteen of Stroustrup. So I understand virtual functions and virtual base. However, I am not to the point where I can implement virtual functions and virtual base without asking: How do you implement them effectively?
>>>>>>>
Ok...Virtual functions. Lets assume you write a app that open a document to read it.
So you write a class (Document) with I/O functions and read function.
Class Document
method: openFile
method: ReadFromFile
method: closeFile
But you realise that there is different kinds of documents (txt, rtf, htm...) and different kinds of documents has different ways to read effectivelly a text from it. Than you could write a subclass for Document:
Class Txt : Document
(method: openFile) //declared in Document
method: ReadFromFile
(method: closeFile) //declared in Document
this class has only one method: ReadFromFile. This is the particular method for dealing with .txt files. The openFile and closeFile are assumed to be implemented in the same way for all kinds of files and do not need to be rewrited for a particular class.
Than you write htm class the same way, with only one method: ReadFromFile.
Ok. Now, you declare the Document pointer, identify the file format and write (txt case):
pointerToDocument = &Txt;
all the other codes to handle the file will use method(args)>. It lets your code more easy to understand and modulable (gets easy to update, insert new stuff, remove other stuff). Lets say you upgrade your program to suport .doc files..you simple write the class as a Document subclass and add the code: pointerToDucment = &Doc;
I don't know if I did a good exemple, but like you, I'm a student, not an expert
>>>>>>>>>>>>>
Under what specific situation do you implement dynamic binding? Please be very specific because I found that neither Deitel & Deitel nor Stroustrup give a convincing example of dynamic binding.
: Lastly, I too want to implement dynimic binding if it is possible to declare *one* object of either the base class or the derived class. The following is *not correct*:
>>>>>>>>>>>>
Dynamic binding. I don't know what it is (in terms of name...I'm brazilian, and I don't know the brazilian equivalent for Dynamic Bynding! heheh )
Jester
Here is an example:
Base Class : Movies
Derived Class #1: Action
Derived Class #2: Comedy
------------------------
Static binding:
Action *aClass = new Action;
cout << aClass->getTitle(); // virtual function
------------------------
------------------------
Dynamic binding:
Action *aClass = new Action;
Movies *aMovies = &aClass;
cout << aMovies->getTitle(); // virtual function
Both Action and Comedy have their own function: getTitle().
With dynamic binding, the program determines which getTitle() the user is talking about.
With static binding, everything is done before run-time.
------------------------
Kuphryn
: Dynamic binding:
:
: Action *aClass = new Action;
:
: Movies *aMovies = &aClass;
:
: cout << aMovies->getTitle(); // virtual function
:
: Both Action and Comedy have their own function: getTitle().
:
: With dynamic binding, the program determines which getTitle() the user is talking about.
>>>>>>>>>>>>>
Well...thats the polimorphism I did in my exemple....
>>>>>>>>>>>
Lastly, I too want to implement dynimic binding if it is possible to declare *one* object of either the base class or the derived class. The following is *not correct*:
------------------------
classBase *cDynamic = new classDerived
------------------------
>>>>>>>>>>>>>>>>
.. how is the exemple above not correct? it's a base-class pointer that receives the addres of a memory containing a new subclass. It works!
your question is just about the pratical implementation of polimorphism? something else?
One more question. In general, is there a performance improvement when using virtual function?
Kuphryn
:
: One more question. In general, is there a performance improvement when using virtual function?
:
: Kuphryn
:
Interesting...
performance improvement? Whell...I don't think so...*I guess*, after a virtual function is called, the program has to figure from what subclass this function should be used. I belive it is more a matter of code-organization rather than optimization.
If you don't have multiple classes, you have no use for virtual functions! Virtual function are only meaningful in class heirarchies.
Imagine you had a drawing program - it has rectangles, triangles, circles, lines, text, bitmaps, etc. These would have things in common, such as position and size, so it would be natural to derive them from a common base class (which I'll call 'Widget').
Now image the part of your program that manages all these Widgets, moves them around, draws them, etc., call it the 'WidgetManager'. The WidgetManager could care less care what the Widgets are, he just needs to be able to move them around and draw them. However, if the methods in the base class Widget are not virtual, he can't treat Widgets generically - he has to have a seperate list for CircleWidgets and TextWidgets, and must iterate through these lists seperatately telling each particular Widget subclass to do the same thing ("draw thyself"). Also, if you add or remove a Widget type from your program, the WidgetManager must be update to reflect the change. At the very least, the WidgetManager will need to be recompiled.
Wouldn't it be nice of the WidgetManager could just deal with Widgets, and not have to worry about whether they were CircleWidets, TriangleWidgets, or MonicaLewinskyWidgets? Well, it can, by making the Widget members virtual.
: null_pointer made a good point at GameDev forums that a pointer takes up very little resource. I believe he implied that even thought virtual requires declaration of multiple class objects, doing so through pointer takes up few resources.
:
: One more question. In general, is there a performance improvement when using virtual function?
No. There is a slight (very slight) performance [italic]penalty[/italic] for using virtual functions. With static binding, the compiler knows exactly which function is being called on an object - it hardcodes the address of that function. With dynamic binding (i.e. virtual functions), the compiler must lookup which function to call in a table. The performance difference boils down to this:
[code=ffffff]
[color=000080]void[/color] function()
{
print([color=bb0000]"Hello, World"[/color]);
}
[color=000080]int[/color] main()
{
[color=000080]void[/color] (*pfunc)() = function;
function(); [color=80a0b0][italic]// direct call[/italic][/color]
pfunc(); [color=80a0b0][italic]// indirect call[/italic][/color]
}
[/code]
The difference between calling a statically bound function and a virtual function is the difference between calling function() and pfunc(), i.e. one level of indirection.
The other hit is in memory. The way virtual functions work (typically) is the compiler generates a 'virtual function table' (vtable) for each class with virtual functions. This table contains the address of each functions of the class. Each instance of that class then carries around an extra, hidden member - a pointer to the vtable. So that adds at least sizeof(memberfunction) bytes (4 bytes on the average modern computer) to each instance of a class that has virtual functions.
However, if you look at the designs that are used [italic]instead[/italic] of virtual functions, they usually have more overhead. For instance, in C++, the WidgetManager might draw the Widgets like this:
[code=ffffff]
[color=000000][b]for[/b][/color] (widgets:iterator it = widgets.begin(); it != widgets.end(); ++it)
it->draw(canvas);
[/code]
Calling the 'draw' by deferencing the vtable point in the Widget instance - very fast.
In C, that routine routine might looks something like:
[code=ffffff]
Node* it;
[color=000000][b]for[/b][/color] (it = widgets->head; it != [color=bb0000]NULL[/color]; it = it->next)
{
[color=000000][b]switch[/b][/color](it->object_type) {
[color=000000][b]case[/b][/color] WidgetCircle:
WidgetCircle_draw(it, canvas);
[color=000000][b]break[/b][/color];
[color=000000][b]case[/b][/color] WidgetText:
WidgetText_draw(it, canvas);
[color=000000][b]break[/b][/color]
}
}
[/code]
Which means (a) each Widget struct must set aside a 'type' field, which (on my machine) uses the same amount of memory as the vtable pointer, and (b) there is a similar switch statement any time you wants to perform an operation on a Widget. That case statement is a far cry slower than a virtual function call.
Cheers,
Eric
Thanks! You cleared up the performance difference between static binding and dynamic binding well.
Kuphryn