1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

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

    Joined:
    Aug 29, 2007
    Messages:
    20
    Likes Received:
    2
    Trophy Points:
    0
    Occupation:
    Software engineer
    Location:
    Bangalore
    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

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
    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

    Joined:
    Jul 12, 2004
    Messages:
    15,285
    Likes Received:
    364
    Trophy Points:
    83
    Moved to Articles as of now. Thanks for letting me know.
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    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

    Joined:
    Aug 29, 2007
    Messages:
    20
    Likes Received:
    2
    Trophy Points:
    0
    Occupation:
    Software engineer
    Location:
    Bangalore
    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

    Joined:
    Jul 12, 2004
    Messages:
    15,285
    Likes Received:
    364
    Trophy Points:
    83
  7. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,285
    Likes Received:
    364
    Trophy Points:
    83
  8. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,285
    Likes Received:
    364
    Trophy Points:
    83

Share This Page