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. virtual inheritance and polymorphism! [modified]

virtual inheritance and polymorphism! [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
oopquestionc++helptutorial
12 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.
  • D Offline
    D Offline
    Dean Seo
    wrote on last edited by
    #1

    Since I found this site, it has helped me improve my skills a lot. I used to ask about MFC but now I need to know the relevancy between virtual inheritance and polymorphism. I tried to find it in Google, but I couldn't find what I'd like to know. Maybe I think it's because virtual inheritence is only used for multiple inheritance, which is considered bad to use. For example, it seems like there is no way to keep polymorphism the way I think it has to be in multiple and virtual inheritance, as you see below.

    class A{};
    class B : public A{};
    class C : public A{};
    class D : public B, public C{};
    int _tmain(int argc, _TCHAR* argv[])
    {
    A* a = new D(); // compile error!
    }

    This seems like a very reasonable compile error to me but why? Is it not an IS-A relationship? I'd like to thoroughly understand this. Also, as you can see in the code below,

    class A{};
    class B : public A{};
    class C : public A{};
    class D : public B, public C{};
    int _tmain(int argc, _TCHAR* argv[])
    {
    B* b = new D(); // works! ..what?
    }

    If A and D are not an IS-A relationship, why does B and D have to be an IS-A relationship? Or something like this.

    class A{};
    class B : public A{};
    class C : public A{
    public:
    virtual void Func(){
    cout << "Called??";
    }
    };
    class D : public B, public C{
    public:
    virtual void Func(){
    cout << "Called!!";
    }
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
    B* b = new D();
    b->Func(); // Error!
    }

    I understand that I can figure out how this works, but since it's a pretty complicated thing, I'd like to know why this happens, THROUGHLY. So I'd like to know where on the internet web pages I can figure all this out so that I can sleep tight! Thanks in advance.

    modified on Tuesday, August 2, 2011 2:13 AM

    P Q C R 4 Replies Last reply
    0
    • D Dean Seo

      Since I found this site, it has helped me improve my skills a lot. I used to ask about MFC but now I need to know the relevancy between virtual inheritance and polymorphism. I tried to find it in Google, but I couldn't find what I'd like to know. Maybe I think it's because virtual inheritence is only used for multiple inheritance, which is considered bad to use. For example, it seems like there is no way to keep polymorphism the way I think it has to be in multiple and virtual inheritance, as you see below.

      class A{};
      class B : public A{};
      class C : public A{};
      class D : public B, public C{};
      int _tmain(int argc, _TCHAR* argv[])
      {
      A* a = new D(); // compile error!
      }

      This seems like a very reasonable compile error to me but why? Is it not an IS-A relationship? I'd like to thoroughly understand this. Also, as you can see in the code below,

      class A{};
      class B : public A{};
      class C : public A{};
      class D : public B, public C{};
      int _tmain(int argc, _TCHAR* argv[])
      {
      B* b = new D(); // works! ..what?
      }

      If A and D are not an IS-A relationship, why does B and D have to be an IS-A relationship? Or something like this.

      class A{};
      class B : public A{};
      class C : public A{
      public:
      virtual void Func(){
      cout << "Called??";
      }
      };
      class D : public B, public C{
      public:
      virtual void Func(){
      cout << "Called!!";
      }
      };
      int _tmain(int argc, _TCHAR* argv[])
      {
      B* b = new D();
      b->Func(); // Error!
      }

      I understand that I can figure out how this works, but since it's a pretty complicated thing, I'd like to know why this happens, THROUGHLY. So I'd like to know where on the internet web pages I can figure all this out so that I can sleep tight! Thanks in advance.

      modified on Tuesday, August 2, 2011 2:13 AM

      P Offline
      P Offline
      Peter_in_2780
      wrote on last edited by
      #2

      Just a partial answer... In your first case, the compiler (along with all us humans ;P ) doesn't know whether the A* should point to an instance of A->B->D or an A->C->D, in other words whether to use A, B and D constructors, or A, C and D. It's a bit hard to see here, but a more complex (subtle) example could show the difference, in terms of class members (fields or methods) unique to B or C. In your second case (that works), this ambiguity doesn't exist. Clear as mud, I know, but OOP is like that. Cheers, Peter

      Software rusts. Simon Stephenson, ca 1994.

      D 1 Reply Last reply
      0
      • D Dean Seo

        Since I found this site, it has helped me improve my skills a lot. I used to ask about MFC but now I need to know the relevancy between virtual inheritance and polymorphism. I tried to find it in Google, but I couldn't find what I'd like to know. Maybe I think it's because virtual inheritence is only used for multiple inheritance, which is considered bad to use. For example, it seems like there is no way to keep polymorphism the way I think it has to be in multiple and virtual inheritance, as you see below.

        class A{};
        class B : public A{};
        class C : public A{};
        class D : public B, public C{};
        int _tmain(int argc, _TCHAR* argv[])
        {
        A* a = new D(); // compile error!
        }

        This seems like a very reasonable compile error to me but why? Is it not an IS-A relationship? I'd like to thoroughly understand this. Also, as you can see in the code below,

        class A{};
        class B : public A{};
        class C : public A{};
        class D : public B, public C{};
        int _tmain(int argc, _TCHAR* argv[])
        {
        B* b = new D(); // works! ..what?
        }

        If A and D are not an IS-A relationship, why does B and D have to be an IS-A relationship? Or something like this.

        class A{};
        class B : public A{};
        class C : public A{
        public:
        virtual void Func(){
        cout << "Called??";
        }
        };
        class D : public B, public C{
        public:
        virtual void Func(){
        cout << "Called!!";
        }
        };
        int _tmain(int argc, _TCHAR* argv[])
        {
        B* b = new D();
        b->Func(); // Error!
        }

        I understand that I can figure out how this works, but since it's a pretty complicated thing, I'd like to know why this happens, THROUGHLY. So I'd like to know where on the internet web pages I can figure all this out so that I can sleep tight! Thanks in advance.

        modified on Tuesday, August 2, 2011 2:13 AM

        Q Offline
        Q Offline
        QuickDeveloper
        wrote on last edited by
        #3

        The first one is a clear case of Diamond Inheritance Problem, As there will be two copies of A in B & C , the compiler will be confused which one to use for D. This is where virtual inheritance steps in. Refer http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8[^] for a start.

        "Every morning I go through Forbes list of 40 richest people in the world. If my name is not in there, I go to work..!!!"

        E D 2 Replies Last reply
        0
        • D Dean Seo

          Since I found this site, it has helped me improve my skills a lot. I used to ask about MFC but now I need to know the relevancy between virtual inheritance and polymorphism. I tried to find it in Google, but I couldn't find what I'd like to know. Maybe I think it's because virtual inheritence is only used for multiple inheritance, which is considered bad to use. For example, it seems like there is no way to keep polymorphism the way I think it has to be in multiple and virtual inheritance, as you see below.

          class A{};
          class B : public A{};
          class C : public A{};
          class D : public B, public C{};
          int _tmain(int argc, _TCHAR* argv[])
          {
          A* a = new D(); // compile error!
          }

          This seems like a very reasonable compile error to me but why? Is it not an IS-A relationship? I'd like to thoroughly understand this. Also, as you can see in the code below,

          class A{};
          class B : public A{};
          class C : public A{};
          class D : public B, public C{};
          int _tmain(int argc, _TCHAR* argv[])
          {
          B* b = new D(); // works! ..what?
          }

          If A and D are not an IS-A relationship, why does B and D have to be an IS-A relationship? Or something like this.

          class A{};
          class B : public A{};
          class C : public A{
          public:
          virtual void Func(){
          cout << "Called??";
          }
          };
          class D : public B, public C{
          public:
          virtual void Func(){
          cout << "Called!!";
          }
          };
          int _tmain(int argc, _TCHAR* argv[])
          {
          B* b = new D();
          b->Func(); // Error!
          }

          I understand that I can figure out how this works, but since it's a pretty complicated thing, I'd like to know why this happens, THROUGHLY. So I'd like to know where on the internet web pages I can figure all this out so that I can sleep tight! Thanks in advance.

          modified on Tuesday, August 2, 2011 2:13 AM

          C Offline
          C Offline
          Chandrasekharan P
          wrote on last edited by
          #4

          Look at this Link. http://msdn.microsoft.com/en-us/library/wcz57btd.aspx[^]

          Every new day is another chance to change your life.

          D 1 Reply Last reply
          0
          • D Dean Seo

            Since I found this site, it has helped me improve my skills a lot. I used to ask about MFC but now I need to know the relevancy between virtual inheritance and polymorphism. I tried to find it in Google, but I couldn't find what I'd like to know. Maybe I think it's because virtual inheritence is only used for multiple inheritance, which is considered bad to use. For example, it seems like there is no way to keep polymorphism the way I think it has to be in multiple and virtual inheritance, as you see below.

            class A{};
            class B : public A{};
            class C : public A{};
            class D : public B, public C{};
            int _tmain(int argc, _TCHAR* argv[])
            {
            A* a = new D(); // compile error!
            }

            This seems like a very reasonable compile error to me but why? Is it not an IS-A relationship? I'd like to thoroughly understand this. Also, as you can see in the code below,

            class A{};
            class B : public A{};
            class C : public A{};
            class D : public B, public C{};
            int _tmain(int argc, _TCHAR* argv[])
            {
            B* b = new D(); // works! ..what?
            }

            If A and D are not an IS-A relationship, why does B and D have to be an IS-A relationship? Or something like this.

            class A{};
            class B : public A{};
            class C : public A{
            public:
            virtual void Func(){
            cout << "Called??";
            }
            };
            class D : public B, public C{
            public:
            virtual void Func(){
            cout << "Called!!";
            }
            };
            int _tmain(int argc, _TCHAR* argv[])
            {
            B* b = new D();
            b->Func(); // Error!
            }

            I understand that I can figure out how this works, but since it's a pretty complicated thing, I'd like to know why this happens, THROUGHLY. So I'd like to know where on the internet web pages I can figure all this out so that I can sleep tight! Thanks in advance.

            modified on Tuesday, August 2, 2011 2:13 AM

            R Offline
            R Offline
            Resmi Anna
            wrote on last edited by
            #5

            Peter has already given a partial answer to your question. just consider the below example

            class A
            {
            public:
            A()
            {
            cout << "A::A\n";
            }
            };
            class B : public A
            {
            public:
            B()
            {
            cout << "B::B\n";
            }
            };
            class C : public B
            {
            public:
            C()
            {
            cout << "C::C\n";
            }
            };
            int main()
            {
            A* a = new C();
            return 0;
            }

            What will be the output A::A B::B C::C right?? means the order of object creation is like A->B->C and C objects reference is being put into A's pointer In your code There are two object creation order like A->B->D and like A->C->D Here compler would be confused which D's reference comes to A's pointer??? That is why there is compilation error. c++ provides us something through which we can overcome this problem. Thats the virtual class. You might have heard of diamond problem in c++. This what happens here. you can change you code like below.

            class A{};
            class B : virtual public A{};
            class C : virtual public A{};
            class D : public B, public C{};
            int _tmain(int argc, _TCHAR* argv[])
            {
            A* a = new D(); // No error!
            }

            note the key word virtual. Now the order of object creation will be like A->B->C->D. you can print some thing in constructure of each class and can see this. In the second code snippet

            class A{};
            class B : public A{};
            class C : public A{};
            class D : public B, public C{};
            int _tmain(int argc, _TCHAR* argv[])
            {
            B* b = new D(); // works! ..what?
            }

            There is no confusion for the compiler even though there are 2 object creation order. One like A->B->D and another like A->C->D. But you have clearly mentioned that D objects refernce goes to B's pointer. So complier will take A->B->D order and put this into B's pointer. But C object also will be created. Now it is clear that why the third code snippet cause an error. B's pointer stores a reference of D object being created in the order A->B->D. There is no Func() function on the way. Is there??

            E D 2 Replies Last reply
            0
            • Q QuickDeveloper

              The first one is a clear case of Diamond Inheritance Problem, As there will be two copies of A in B & C , the compiler will be confused which one to use for D. This is where virtual inheritance steps in. Refer http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8[^] for a start.

              "Every morning I go through Forbes list of 40 richest people in the world. If my name is not in there, I go to work..!!!"

              E Offline
              E Offline
              Emilio Garavaglia
              wrote on last edited by
              #6

              The compliler has no problem in creating the D object with two A-s in it. The problem is the assignment to the A* (that is ambiguous since there are two of them), not the D creation.

              2 bugs found. > recompile ... 65534 bugs found. :doh:

              D 1 Reply Last reply
              0
              • R Resmi Anna

                Peter has already given a partial answer to your question. just consider the below example

                class A
                {
                public:
                A()
                {
                cout << "A::A\n";
                }
                };
                class B : public A
                {
                public:
                B()
                {
                cout << "B::B\n";
                }
                };
                class C : public B
                {
                public:
                C()
                {
                cout << "C::C\n";
                }
                };
                int main()
                {
                A* a = new C();
                return 0;
                }

                What will be the output A::A B::B C::C right?? means the order of object creation is like A->B->C and C objects reference is being put into A's pointer In your code There are two object creation order like A->B->D and like A->C->D Here compler would be confused which D's reference comes to A's pointer??? That is why there is compilation error. c++ provides us something through which we can overcome this problem. Thats the virtual class. You might have heard of diamond problem in c++. This what happens here. you can change you code like below.

                class A{};
                class B : virtual public A{};
                class C : virtual public A{};
                class D : public B, public C{};
                int _tmain(int argc, _TCHAR* argv[])
                {
                A* a = new D(); // No error!
                }

                note the key word virtual. Now the order of object creation will be like A->B->C->D. you can print some thing in constructure of each class and can see this. In the second code snippet

                class A{};
                class B : public A{};
                class C : public A{};
                class D : public B, public C{};
                int _tmain(int argc, _TCHAR* argv[])
                {
                B* b = new D(); // works! ..what?
                }

                There is no confusion for the compiler even though there are 2 object creation order. One like A->B->D and another like A->C->D. But you have clearly mentioned that D objects refernce goes to B's pointer. So complier will take A->B->D order and put this into B's pointer. But C object also will be created. Now it is clear that why the third code snippet cause an error. B's pointer stores a reference of D object being created in the order A->B->D. There is no Func() function on the way. Is there??

                E Offline
                E Offline
                Emilio Garavaglia
                wrote on last edited by
                #7

                Resmi Anna wrote:

                That is why there is compilation error. c++ provides us something through which we can overcome this problem.

                That's improper. virtual bases are not "the solution to ambiguity". Are just "another thing". If A is inherited twice because it must be inherited twice, it is not removing one of them that you "solve" THE problem. You actually soleve A problem, and introduce something else. The layout of D in the first case is

                D[B[A]C[A]]

                and in the second case is

                D[B[.]C[.]A]

                (note: '.' is a pointer to A, internal to the compiler generated structure) That's not equivalent to the first.

                2 bugs found. > recompile ... 65534 bugs found. :doh:

                1 Reply Last reply
                0
                • P Peter_in_2780

                  Just a partial answer... In your first case, the compiler (along with all us humans ;P ) doesn't know whether the A* should point to an instance of A->B->D or an A->C->D, in other words whether to use A, B and D constructors, or A, C and D. It's a bit hard to see here, but a more complex (subtle) example could show the difference, in terms of class members (fields or methods) unique to B or C. In your second case (that works), this ambiguity doesn't exist. Clear as mud, I know, but OOP is like that. Cheers, Peter

                  Software rusts. Simon Stephenson, ca 1994.

                  D Offline
                  D Offline
                  Dean Seo
                  wrote on last edited by
                  #8

                  Thank you!

                  1 Reply Last reply
                  0
                  • Q QuickDeveloper

                    The first one is a clear case of Diamond Inheritance Problem, As there will be two copies of A in B & C , the compiler will be confused which one to use for D. This is where virtual inheritance steps in. Refer http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8[^] for a start.

                    "Every morning I go through Forbes list of 40 richest people in the world. If my name is not in there, I go to work..!!!"

                    D Offline
                    D Offline
                    Dean Seo
                    wrote on last edited by
                    #9

                    Thanks!!!

                    1 Reply Last reply
                    0
                    • C Chandrasekharan P

                      Look at this Link. http://msdn.microsoft.com/en-us/library/wcz57btd.aspx[^]

                      Every new day is another chance to change your life.

                      D Offline
                      D Offline
                      Dean Seo
                      wrote on last edited by
                      #10

                      Thanks. I will.

                      1 Reply Last reply
                      0
                      • E Emilio Garavaglia

                        The compliler has no problem in creating the D object with two A-s in it. The problem is the assignment to the A* (that is ambiguous since there are two of them), not the D creation.

                        2 bugs found. > recompile ... 65534 bugs found. :doh:

                        D Offline
                        D Offline
                        Dean Seo
                        wrote on last edited by
                        #11

                        Thank you!

                        1 Reply Last reply
                        0
                        • R Resmi Anna

                          Peter has already given a partial answer to your question. just consider the below example

                          class A
                          {
                          public:
                          A()
                          {
                          cout << "A::A\n";
                          }
                          };
                          class B : public A
                          {
                          public:
                          B()
                          {
                          cout << "B::B\n";
                          }
                          };
                          class C : public B
                          {
                          public:
                          C()
                          {
                          cout << "C::C\n";
                          }
                          };
                          int main()
                          {
                          A* a = new C();
                          return 0;
                          }

                          What will be the output A::A B::B C::C right?? means the order of object creation is like A->B->C and C objects reference is being put into A's pointer In your code There are two object creation order like A->B->D and like A->C->D Here compler would be confused which D's reference comes to A's pointer??? That is why there is compilation error. c++ provides us something through which we can overcome this problem. Thats the virtual class. You might have heard of diamond problem in c++. This what happens here. you can change you code like below.

                          class A{};
                          class B : virtual public A{};
                          class C : virtual public A{};
                          class D : public B, public C{};
                          int _tmain(int argc, _TCHAR* argv[])
                          {
                          A* a = new D(); // No error!
                          }

                          note the key word virtual. Now the order of object creation will be like A->B->C->D. you can print some thing in constructure of each class and can see this. In the second code snippet

                          class A{};
                          class B : public A{};
                          class C : public A{};
                          class D : public B, public C{};
                          int _tmain(int argc, _TCHAR* argv[])
                          {
                          B* b = new D(); // works! ..what?
                          }

                          There is no confusion for the compiler even though there are 2 object creation order. One like A->B->D and another like A->C->D. But you have clearly mentioned that D objects refernce goes to B's pointer. So complier will take A->B->D order and put this into B's pointer. But C object also will be created. Now it is clear that why the third code snippet cause an error. B's pointer stores a reference of D object being created in the order A->B->D. There is no Func() function on the way. Is there??

                          D Offline
                          D Offline
                          Dean Seo
                          wrote on last edited by
                          #12

                          Thanks!!!!

                          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