Static Binding & Dynamic Binding :: C++

Started by
17 comments, last by kuphryn 22 years, 3 months ago
quote:The following is an explicit cast:
      base* p = new derived;p->member_function_1();p->member_function_2();      

quote:The above line containing the pointer declaration contains an implicit cast,...


You appear to have contradicted yourself. I believe you meant "implicit" for both.

Edited by - Zipster on December 31, 2001 9:20:52 PM
Advertisement
Zipster:

I am not sure that I understand what you are saying. Are you responding this:


quote:Original post by null_pointer

(Although, if you implement operator new you will find that it returns void*, this is because the compiler handles the constructor calls and type-checking for the implementer, and it does not change the fact that "new" returns a typed pointer.)


When I said "operator new" I was referring to the C++ operator that you overload, and when I said "new" I was referring to the C++ new expression. They are not the same thing. The expression refers to the low-level object initialization (such as the virtual function table pointer initialization), constructors, and the type checking, none of which are handled by the "operator new" that you may overload:

  #include <cmalloc>#include <stdexcept> using std::malloc;using std::bad_alloc; // find the low-level initialization, constructor call(s), and type-checking in here, if you can: void* operator new (size_t size){  if( !size ) size = 1;   new_handler h = set_new_handler(0);  set_new_handler(h);   for( ;; )  {    if( !p )    {      void* p = malloc(size);            if( p ) return p;      else if( h ) h();      else         throw bad_alloc();    }  }}  


Edited by - null_pointer on December 31, 2001 10:58:40 PM
Casting is a compile-time thing. normally, for the compiler to write code, it needs to look at the data-type. when types are contradictory, the compiler tells you. by casting, you tell the compiler that its cool, and that it can proceed.

its simply a naming/size-recognition system. casting does not allocated more or less space.

class a = (a) new b;
//tell the compiler that b and a are similar enough to copy
null_pointer: I don''t see how that is considered a cast, I have never ever seen anyone call it a cast. Casting is where you tell the compiler to look at data in a new way, because in that particular case you know more than the compiler about the object''s type. Also I think you are confusing kuphryn with a lot of implementation information that isn''t relevant to his question.

kuphryn: virtual functions and inheritance exist to make something called polymorphism work. Because of a limitation in C++ (a fairly reasonable one) you can only get objects to behave polymorphically if you use pointers or references.

Ok here''s an example. We''re going to make a little controller class to control a creature in your game. Assume that we have some constants or enums of type called Action. Every turn the creature checks whatever is controlling it to see what it should do.

  class Controller //the base class{    virtual Action Decide() = 0;};class AgressiveAI : public Controller{  Action Decide()  {    if(PlayerAhead()) return CHARGE;    if(PlayerInRange()) return HACK_AND_SLASH;    else return GROWL;  }};class PassiveAI : public Controller{  Action Decide()  {    if(PlayerAhead()) return TURN_AND_FLEE;    if(PlayerInRange()) return COWER;    else return PICK_DAISYS;  }};class PlayerControlled : public Controller{  Action Decide()  {    if(LeftClick()) return HACK_AND_SLASH;    if(RightClick()) return CAST_FIREBALL;    if(SPACEBAR_PRESSED) return JUMP;    //etc  }};  


So you could use the same class for three different creatures but they would all behave very differently depending on the value of their pointer to their controller class. The whole point of virtual functions is to allow you to vary behavior. There is no other reason. How can you vary behavior using only one class? You just can''t have variation (using this method) unless you have multiple.
Thanks everyone. I see a clearer picture of static binding, but most important, virtual functions and dynamic binding now.

Kuphryn

Edited by - kuphryn on January 1, 2002 3:12:53 AM
Zipster: LOL...man, I must have been really tired. I see what you are saying now. Thanks for correcting me!


quote:Original post by kuphryn

You made it look like in:

ClassX *CX = new ClassX;

"new ClassX" *is not* deleted in:

delete CX;

It is just "CX" that is gone.

That is where I am confused from your explanation.


"CX" is a pointer that refers to "new ClassX." The C++ "delete" expression takes a pointer and destroys the object it refers to - so long as the object itself was allocated with "new". Together, new and delete allow you to manage the lifetime of the object manually, as opposed to simply declaring objects whose lifetimes are determined by language rules (i.e., their scope in the program).

The following two examples are basically identical in terms of object construction/destruction, because of where the new and delete expressions are placed:

  // example 1 int main(){  base* p = new derived;   // ...   delete p;   return 0;}  


  // example 2 int main(){  derived d;   // ...   return 0;}  


The usefulness of new and delete is that you can place them in different functions or destroy the object before the function has ended, and so on. As long as you store the pointer returned by new, you can pass it to delete to properly destroy the object.

In this situation, the pointer acts somewhat like a claim check at a repair shop. When you bring your item in to get repaired, the clerk gives you a claim check. You need that claim check to refer to the item by proving that you are the one who brought the item into the store. When the item has been repaired, you give the clerk the claim check, pay the bill, and he will give you back the repaired item.

The difference is that when you call "new" you get both a newly constructed object and the pointer and when you call delete you must give it back the pointer so that it knows which object to destroy.

  base* p = new derived;delete p;  


Take away the pointer, and how do you specify which object should be deleted? The object you created with "new derived" has no name:

  new derived; // legal, but dumbdelete ;     // huh?  


Without a pointer you have no way of referring to the object...
quote:Original post by Anonymous Poster

I don''t see how that is considered a cast, I have never ever seen anyone call it a cast. Casting is where you tell the compiler to look at data in a new way, because in that particular case you know more than the compiler about the object''s type.


You are correct, and I was not. I do not know why I thought that cast and conversion were the same thing. A cast is where you direct the compiler to perform an explicit conversion; an implicit conversion is (obviously) performed without a cast. Otherwise, it would not be implicit. Good point!


quote:Original post by Anonymous Poster

Also I think you are confusing kuphryn with a lot of implementation information that isn''t relevant to his question.


How so?
Okay. Thanks everyone. I appreciate the insights.

null_pointer: You really cleared up a lot about new and delete.

Kuphryn
quote:
Is there an advantage to using dynamic binding instead of static binding?

Dynamic binding lets you alter behavior at run-time.

Edited by - Magmai Kai Holmlor on January 1, 2002 3:30:33 PM
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement