1. We have moved from vBulletin to XenForo and you are viewing the site in the middle of the move. Though the functional aspect of everything is working fine, we are still working on other changes including the new design on Xenforo.
    Dismiss Notice

Cross Delegation or Delegate to a sister class

Discussion in 'C++' started by jayaraj_ev, Feb 4, 2009.

  1. jayaraj_ev

    jayaraj_ev New Member

    In c++ you would have heard about famous Dreaded Diamond problem, where a class appears more than once in the inheritance hierarchy.
    for eg:

    Code:
    #include <iostream>
    using namespace std;
    class A
    { 
      public:
        int data;
    };
    class B : public A
    {
    };
    class C : public A
    {
    };
    class D: public B, public C
    {
      public :
         void function(void)
         {
              data = 1;
         }
    };
    
    int main (void)
    {
       D d;
        d.function();
       return 0;
    }
    Here there is ambiguity as A is inherited twice so there are two copies of A::data in the object of D d.This Piece of code can be corrected if
    Code:
    void function(void)
    {
       B::data = 1; or C::data = 1;
    }
    
    But this is not the full solution we require, instead we use virtual inheritance. where class B and C virtually inherit class A. so that only one copy of class A member data is found in D d object.
    Code:
    class B : virtual public A
    {
    };
    class C : virtual public A
    {
    };
    
    A powerful technique for customizing the behavior of polymorphic classes called cross delegation or Delegate to a sister class.
    for eg:
    Code:
    #include <iostream>
    using namespace std;
    class A
    {
      public:
        virtual void function1(void) = 0;
        virtual void function2(void) = 0;
    };
    
    class B : virtual public A
    {
      public:
      void function1(void)
      {
        cout<<"FUNCTION ONE"<<endl;
      }
    };
    
    class C : virtual public A
    {
      public:
      void function2(void)
      {
        cout<<"FUNCTION TWO"<<endl;
      }
    };
    
    class D : public B, public C
    {
    
    };
    
    int main (void)
    {
      D d;
      d.function1();
      d.function2();
      return 0;
    }
    
    Here class A becomes a abstract class as the methods function1() and function2() are pure virtual functions.Which means in the Vtable of this class, these functions addresses are set to Null.

    When Class B and C inherits class A and does not contain the definitions of both functions they too become abstract. so when class D inherits it both B and C (where class B & C should have been inherited class A virtually) the Vtable of class D contains:
    &B::function1()
    &C::function2()

    so when we create object of D d it gets created without any problem and definitions of the functions are picked from both classes.
     
    shabbir likes this.
  2. asadullah.ansari

    asadullah.ansari TechCake

    Put it into right place. Means this is under queries and discussion. Go to

    Programming and Web Development Forum > Go4Expert > Articles / Source Code > Programming

    and click on submit article.
     
  3. shabbir

    shabbir Administrator Staff Member

    Moved to Articles as of now. Thanks for letting me know.
     
  4. xpi0t0s

    xpi0t0s Mentor

    Generates a couple of warnings in Visual Studio 2005:

    warning C4250: 'D' : inherits 'B::B::function1' via dominance
    see declaration of 'B::function1'
    warning C4250: 'D' : inherits 'C::C::function2' via dominance
    see declaration of 'C::function2'

    http://msdn.microsoft.com/en-us/library/6b3sy7ae(VS.80).aspx

    The technique may be powerful but it's one of those neat tricks in C++ where you can write perfectly valid code in one place and get an error in another. If you implement B::function2(), then you get an error (not a warning) on the "d.function2();" line.

    Code:
    class B : virtual public A
    {
      public:
      void function1(void)
      {
        cout<<"FUNCTION ONE"<<endl;
      }
      void function2(void)
      {
    	  cout<<"B::FUNCTION TWO"<<endl;
      }
    };
    
    .\g04e.cpp(56) : error C2385: ambiguous access of 'function2'
    could be the 'function2' in base 'B'
    or could be the 'function2' in base 'C'
    .\g04e.cpp(56) : error C3861: 'function2': identifier not found

    and on line 56 we have:

    d.function2();

    The call to function2() could well be in a file you haven't touched, and if you're using a compiler that doesn't report errors and warnings as comprehensively as VS2005 then you could be in for some serious head scratching.

    For example if d.function2() is in some other file, then probably this will result in a linker error.
     
  5. jayaraj_ev

    jayaraj_ev New Member

    Hi,
    Actually this concept just explains what is cross delegation and Your code should be written such way that there are no ambiguity.
     
  6. shabbir

    shabbir Administrator Staff Member

  7. shabbir

    shabbir Administrator Staff Member

  8. shabbir

    shabbir Administrator Staff Member

Share This Page