Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Late Binding Concept

Late Binding Concept

Scheduled Pinned Locked Moved C / C++ / MFC
wpfwcfquestion
15 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A AmbiguousName

    Hello. I am little confused in Late Binding Concept (although I understand it theoretically) as I could not understand it programatically. I am defining two classes here and then casting and using their pointers. CBaseClass void CBaseClass::Function() // this is virtual function { cout<<"\nBase Class."; } CChildClass void CChildClass::Function() // overriden virtual function { cout<<"\nChild Class."; } MainClass void main() { CBaseClass* pBase = new cBaseClass(); CChildClass* pChild = (CChildClass*)pBase; pBase->Function(); pChild->Function(); } What should the two function calls produce in MainClass. I think it should produce BaseClass. ChildClass. But it actually produces BaseClass. BaseClass. What is wrong with my understanding. Thanks

    This world is going to explode due to international politics, SOON.

    L Offline
    L Offline
    Lost User
    wrote on last edited by
    #3

    I just tried this and it produces the expected output:

    Base Class.
    Child Class.

    One of these days I'm going to think of a really clever signature.

    CPalliniC 1 Reply Last reply
    0
    • A AmbiguousName

      Hello. I am little confused in Late Binding Concept (although I understand it theoretically) as I could not understand it programatically. I am defining two classes here and then casting and using their pointers. CBaseClass void CBaseClass::Function() // this is virtual function { cout<<"\nBase Class."; } CChildClass void CChildClass::Function() // overriden virtual function { cout<<"\nChild Class."; } MainClass void main() { CBaseClass* pBase = new cBaseClass(); CChildClass* pChild = (CChildClass*)pBase; pBase->Function(); pChild->Function(); } What should the two function calls produce in MainClass. I think it should produce BaseClass. ChildClass. But it actually produces BaseClass. BaseClass. What is wrong with my understanding. Thanks

      This world is going to explode due to international politics, SOON.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #4

      The code you have shown above does not match the code you are using. If I change it to the following, then it produces the results that you see.

      class CBaseClass
      {
      public:
      virtual void Function() // this is virtual function
      {
      cout<<"\nBase Class.";
      }
      };

      class CChildClass : CBaseClass
      {
      public:
      void Function() // overriden virtual function
      {
      cout<<"\nChild Class.";
      }
      };

      One of these days I'm going to think of a really clever signature.

      1 Reply Last reply
      0
      • L Lost User

        I just tried this and it produces the expected output:

        Base Class.
        Child Class.

        One of these days I'm going to think of a really clever signature.

        CPalliniC Offline
        CPalliniC Offline
        CPallini
        wrote on last edited by
        #5

        It maybe but Are you sure? What compiler are you using? What code? What else? :-) Anyway

        CBaseClass * pBase = new CBaseClass();
        CChildClass * pChild = (CChildClass *) pBase;

        is a gross mistake.

        Veni, vidi, vici.

        In testa che avete, signor di Ceprano?

        L 1 Reply Last reply
        0
        • CPalliniC CPallini

          It maybe but Are you sure? What compiler are you using? What code? What else? :-) Anyway

          CBaseClass * pBase = new CBaseClass();
          CChildClass * pChild = (CChildClass *) pBase;

          is a gross mistake.

          Veni, vidi, vici.

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #6

          Exactly so, but as so often happens, the OP has only given us part of the story.

          One of these days I'm going to think of a really clever signature.

          1 Reply Last reply
          0
          • A AmbiguousName

            Hello. I am little confused in Late Binding Concept (although I understand it theoretically) as I could not understand it programatically. I am defining two classes here and then casting and using their pointers. CBaseClass void CBaseClass::Function() // this is virtual function { cout<<"\nBase Class."; } CChildClass void CChildClass::Function() // overriden virtual function { cout<<"\nChild Class."; } MainClass void main() { CBaseClass* pBase = new cBaseClass(); CChildClass* pChild = (CChildClass*)pBase; pBase->Function(); pChild->Function(); } What should the two function calls produce in MainClass. I think it should produce BaseClass. ChildClass. But it actually produces BaseClass. BaseClass. What is wrong with my understanding. Thanks

            This world is going to explode due to international politics, SOON.

            P Offline
            P Offline
            pasztorpisti
            wrote on last edited by
            #7

            The bug in your code is obvious. CPallini already gave you the correct code but I feel this is something that needs further clarification. The bug is the following, and its a major bug in its current context:

            CChildClass* pChild = (CChildClass*)pBase;

            There are 2 kinds of static casts: downcast and upcast. If you are drawing the uml diagram of your class hierarchy then it looks like a tree with its root node (base class) at the top of the diagram. Down and upcast are named based on the direction of the cast in this tree so an upcast means that you cast a derived class to one of its base classes in the hierarchy, this type of cast is safe, you don't have to mark it explicitly in your code because the compiler does it automatically for you:

            Derived * d = new Derived;
            Base* b = d;

            However downcasts are not only dangerous but they usually mean that you committed a design mistake. A base class can have a lot of derived classes and if you are casting a base class to one of its derived classes than its a bug if the actual object isn't an instance of the downcast type or its descendants. People often say that dowcasts defeat the whole purpose of polymorphism/late binding. Example:

            class Base;
            class A : public Base;
            class B : public Base;
            Base* b = new B;
            A* p = (A*)b; // huge mistake because b points to a B instance so the code that uses p can crash anytime if you are not lucky!!!!

            So why doesn't your code crash??? Because you were lucky and currently in your simple example the binary representation of instances created by the compiler for your base and derived classes are probably identical, they just differ in their vtable pointer but in any more complex situations it could easily crash. OK, so when you have a complex hierarchy and you call a virtual function on a base class pointer then which method is executed??? It depends on which object have you actually created! (with new). Since in your example you created just a Base instance it would be magic to see executing the method of the derived class, and its just luck that using the pointer that you filled with your invalid downcast haven't crashed your program. So based on what we have learned up until now you should only use upcasts that are done automatically for you by the compiler, for example:

            CBaseClass* p = new CChildClass; // the compiler automatically upcasts the CChildClass* to CBaseClass*
            p->Function(); // calls the Function

            CPalliniC C C 3 Replies Last reply
            0
            • P pasztorpisti

              The bug in your code is obvious. CPallini already gave you the correct code but I feel this is something that needs further clarification. The bug is the following, and its a major bug in its current context:

              CChildClass* pChild = (CChildClass*)pBase;

              There are 2 kinds of static casts: downcast and upcast. If you are drawing the uml diagram of your class hierarchy then it looks like a tree with its root node (base class) at the top of the diagram. Down and upcast are named based on the direction of the cast in this tree so an upcast means that you cast a derived class to one of its base classes in the hierarchy, this type of cast is safe, you don't have to mark it explicitly in your code because the compiler does it automatically for you:

              Derived * d = new Derived;
              Base* b = d;

              However downcasts are not only dangerous but they usually mean that you committed a design mistake. A base class can have a lot of derived classes and if you are casting a base class to one of its derived classes than its a bug if the actual object isn't an instance of the downcast type or its descendants. People often say that dowcasts defeat the whole purpose of polymorphism/late binding. Example:

              class Base;
              class A : public Base;
              class B : public Base;
              Base* b = new B;
              A* p = (A*)b; // huge mistake because b points to a B instance so the code that uses p can crash anytime if you are not lucky!!!!

              So why doesn't your code crash??? Because you were lucky and currently in your simple example the binary representation of instances created by the compiler for your base and derived classes are probably identical, they just differ in their vtable pointer but in any more complex situations it could easily crash. OK, so when you have a complex hierarchy and you call a virtual function on a base class pointer then which method is executed??? It depends on which object have you actually created! (with new). Since in your example you created just a Base instance it would be magic to see executing the method of the derived class, and its just luck that using the pointer that you filled with your invalid downcast haven't crashed your program. So based on what we have learned up until now you should only use upcasts that are done automatically for you by the compiler, for example:

              CBaseClass* p = new CChildClass; // the compiler automatically upcasts the CChildClass* to CBaseClass*
              p->Function(); // calls the Function

              CPalliniC Offline
              CPalliniC Offline
              CPallini
              wrote on last edited by
              #8

              :thumbsup:

              Veni, vidi, vici.

              In testa che avete, signor di Ceprano?

              P 1 Reply Last reply
              0
              • CPalliniC CPallini

                :thumbsup:

                Veni, vidi, vici.

                P Offline
                P Offline
                pasztorpisti
                wrote on last edited by
                #9

                Thanks!

                1 Reply Last reply
                0
                • P pasztorpisti

                  The bug in your code is obvious. CPallini already gave you the correct code but I feel this is something that needs further clarification. The bug is the following, and its a major bug in its current context:

                  CChildClass* pChild = (CChildClass*)pBase;

                  There are 2 kinds of static casts: downcast and upcast. If you are drawing the uml diagram of your class hierarchy then it looks like a tree with its root node (base class) at the top of the diagram. Down and upcast are named based on the direction of the cast in this tree so an upcast means that you cast a derived class to one of its base classes in the hierarchy, this type of cast is safe, you don't have to mark it explicitly in your code because the compiler does it automatically for you:

                  Derived * d = new Derived;
                  Base* b = d;

                  However downcasts are not only dangerous but they usually mean that you committed a design mistake. A base class can have a lot of derived classes and if you are casting a base class to one of its derived classes than its a bug if the actual object isn't an instance of the downcast type or its descendants. People often say that dowcasts defeat the whole purpose of polymorphism/late binding. Example:

                  class Base;
                  class A : public Base;
                  class B : public Base;
                  Base* b = new B;
                  A* p = (A*)b; // huge mistake because b points to a B instance so the code that uses p can crash anytime if you are not lucky!!!!

                  So why doesn't your code crash??? Because you were lucky and currently in your simple example the binary representation of instances created by the compiler for your base and derived classes are probably identical, they just differ in their vtable pointer but in any more complex situations it could easily crash. OK, so when you have a complex hierarchy and you call a virtual function on a base class pointer then which method is executed??? It depends on which object have you actually created! (with new). Since in your example you created just a Base instance it would be magic to see executing the method of the derived class, and its just luck that using the pointer that you filled with your invalid downcast haven't crashed your program. So based on what we have learned up until now you should only use upcasts that are done automatically for you by the compiler, for example:

                  CBaseClass* p = new CChildClass; // the compiler automatically upcasts the CChildClass* to CBaseClass*
                  p->Function(); // calls the Function

                  C Offline
                  C Offline
                  Chris Meech
                  wrote on last edited by
                  #10

                  :thumbsup: Good explanation about the perils of upcasting and downcasting and how in this simple example the downcasting worked, but that in a real world case, it would likely crash. :)

                  Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]

                  P 1 Reply Last reply
                  0
                  • C Chris Meech

                    :thumbsup: Good explanation about the perils of upcasting and downcasting and how in this simple example the downcasting worked, but that in a real world case, it would likely crash. :)

                    Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]

                    P Offline
                    P Offline
                    pasztorpisti
                    wrote on last edited by
                    #11

                    Thank you!

                    1 Reply Last reply
                    0
                    • P pasztorpisti

                      The bug in your code is obvious. CPallini already gave you the correct code but I feel this is something that needs further clarification. The bug is the following, and its a major bug in its current context:

                      CChildClass* pChild = (CChildClass*)pBase;

                      There are 2 kinds of static casts: downcast and upcast. If you are drawing the uml diagram of your class hierarchy then it looks like a tree with its root node (base class) at the top of the diagram. Down and upcast are named based on the direction of the cast in this tree so an upcast means that you cast a derived class to one of its base classes in the hierarchy, this type of cast is safe, you don't have to mark it explicitly in your code because the compiler does it automatically for you:

                      Derived * d = new Derived;
                      Base* b = d;

                      However downcasts are not only dangerous but they usually mean that you committed a design mistake. A base class can have a lot of derived classes and if you are casting a base class to one of its derived classes than its a bug if the actual object isn't an instance of the downcast type or its descendants. People often say that dowcasts defeat the whole purpose of polymorphism/late binding. Example:

                      class Base;
                      class A : public Base;
                      class B : public Base;
                      Base* b = new B;
                      A* p = (A*)b; // huge mistake because b points to a B instance so the code that uses p can crash anytime if you are not lucky!!!!

                      So why doesn't your code crash??? Because you were lucky and currently in your simple example the binary representation of instances created by the compiler for your base and derived classes are probably identical, they just differ in their vtable pointer but in any more complex situations it could easily crash. OK, so when you have a complex hierarchy and you call a virtual function on a base class pointer then which method is executed??? It depends on which object have you actually created! (with new). Since in your example you created just a Base instance it would be magic to see executing the method of the derived class, and its just luck that using the pointer that you filled with your invalid downcast haven't crashed your program. So based on what we have learned up until now you should only use upcasts that are done automatically for you by the compiler, for example:

                      CBaseClass* p = new CChildClass; // the compiler automatically upcasts the CChildClass* to CBaseClass*
                      p->Function(); // calls the Function

                      C Offline
                      C Offline
                      Chuck OToole
                      wrote on last edited by
                      #12

                      +5. Great explanation. For me too, I've been reversing upcast and downcast terms, didn't think of the diagram. Saw the obvious error in his example though.

                      P 2 Replies Last reply
                      0
                      • C Chuck OToole

                        +5. Great explanation. For me too, I've been reversing upcast and downcast terms, didn't think of the diagram. Saw the obvious error in his example though.

                        P Offline
                        P Offline
                        pasztorpisti
                        wrote on last edited by
                        #13

                        Thank you!

                        1 Reply Last reply
                        0
                        • C Chuck OToole

                          +5. Great explanation. For me too, I've been reversing upcast and downcast terms, didn't think of the diagram. Saw the obvious error in his example though.

                          P Offline
                          P Offline
                          pasztorpisti
                          wrote on last edited by
                          #14

                          Regarding the upcast/downcast naming: A lot of coders exchange these names so when someone starts using them I always ask him to clarify how to interpret "his upcast" right at the start of the conversation. I also used them in reverse order for a long time until reading some uml docs that clarified it for me. For some reason thinking that upcast is casting up to a higher level smarter derived class seemed to be more logical for me. :-)

                          C 1 Reply Last reply
                          0
                          • P pasztorpisti

                            Regarding the upcast/downcast naming: A lot of coders exchange these names so when someone starts using them I always ask him to clarify how to interpret "his upcast" right at the start of the conversation. I also used them in reverse order for a long time until reading some uml docs that clarified it for me. For some reason thinking that upcast is casting up to a higher level smarter derived class seemed to be more logical for me. :-)

                            C Offline
                            C Offline
                            Chuck OToole
                            wrote on last edited by
                            #15

                            Which is how I use "upcast", to a "bigger" container, the derived class. Of course, that's just a convenience notation. The real idea is

                            Cast Derived to Base - OK
                            Cast Base to Derived - Bad

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups