Cross Delegation or Delegate to a sister class

jayaraj_ev's Avatar author of Cross Delegation or Delegate to a sister class
This is an article on Cross Delegation or Delegate to a sister class in C++.
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 like this
0
asadullah.ansari's Avatar, Join Date: Jan 2008
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.
0
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Quote:
Originally Posted by asadullah.ansari View Post
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.
Moved to Articles as of now. Thanks for letting me know.
0
xpi0t0s's Avatar, Join Date: Aug 2004
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/libr...ae(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.
0
jayaraj_ev's Avatar, Join Date: Aug 2007
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
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/libr...ae(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.
Hi,
Actually this concept just explains what is cross delegation and Your code should be written such way that there are no ambiguity.
0
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Nominate this article for Article of the month for February 2009
0
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Vote for this article for Article of the month February 2009
0
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
This article is winner of Article of the month for February 2009