• Advertisement
Sign in to follow this  

Calling functions with multiple derived classes

This topic is 3839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to do something in a program that I believe is quite similar to double dispatch, but I was wondering if there is a better way without mucking all my classes. I have a base class, Animal, and two sub-classes, Tiger and Deer. I load up an array of animals, and for each pair I call Interact(). I desire that the call to interact would select the appropriate call based on the types (i.e. derived types) of the arguments, and not just always call Interact( Animal, Animal ). Is there a way to accomplish this? Sample code (C#):
using System;
using System.Collections.Generic;
using System.Text;

namespace Test
{
    class Animal
    {
        public virtual void makeSound()  { System.Console.Out.WriteLine( "Generic animal noise" ); }
    };

    class Deer : Animal
    {
        public override void makeSound() { System.Console.Out.WriteLine( "Deer make no sound." ); }
    }

    class Tiger : Animal
    {
        public override void makeSound() { System.Console.Out.WriteLine( "Rawr from the Tiger" ); }
    }

    class MainClass
    {
        static void Interact( Animal a, Animal b )
        {
            System.Console.Out.WriteLine( "Generic Interaction" );
        }

        static void Interact( Deer d, Deer t )
        {
            System.Console.Out.WriteLine( "New deer produced." );
        }

        static void Interact( Tiger d, Tiger t )
        {
            System.Console.Out.WriteLine( "New tiger produced" );
        }

        static void Interact( Deer d, Tiger t )
        {
            System.Console.Out.WriteLine( "There is now one less deer in existance" );
        }

        public static void Main( string[] Args )
        {
            Animal[] Animals = new Animal[ 4 ];

            Animals[ 0 ] = new Deer();
            Animals[ 1 ] = new Deer();
            Animals[ 2 ] = new Tiger();
            Animals[ 3 ] = new Tiger();

            for( int i = 0; i < Animals.Length; i++ )
                Animals[ i ].makeSound();

            System.Console.Out.WriteLine();

            for( int i = 0; i < Animals.Length; i++ )
                for( int j = i + 1; j < Animals.Length; j++ )
                    Interact( Animals[ i ], Animals[ j ] );
        }
    }
}

The output is always a string of "Generic Interaction" whereas it should in fact be: New deer produced. There is now one less deer in existance There is now one less deer in existance There is now one less deer in existance There is now one less deer in existance New tiger produced Any help would be appreciated, in any language. Thank you very much for your time.

Share this post


Link to post
Share on other sites
Advertisement
Yep, this is double dispatch. Unfortunately, C++ has no natural way to express dynamically typed double dispatch.

One way to deal with it is to give each type a code (an enum starting at 0, say). Then, in a hash table, register an interaction function for any given pair of types that you care about. Then, when interacting, look up the pair in the hash table, and call the function (or interface/object) registered there.

The nice thing about it is that you can add new interactions/behaviors without touching the objects themselves at all. One draw-back is that you, typically, need to make the interaction functions friends of the implementation of each of your animals. Another draw-back is that the dispatching is slower than just a function call.

Share this post


Link to post
Share on other sites
In a language like C#, with reflection, you can use object.GetType() to extract the actual dynamic type of the argument. Then, you can use a hashtable as suggested, or work on a more complex lattice traversal scheme. It's certainly possible to create a "dynamic dispatcher" object which builds an internal lattice and then emulated dynamic dispatch on-the-fly.

Share this post


Link to post
Share on other sites
This should be what you are looking for;
http://www.arcadianvisions.com/downloads/MultipleDispatch/multiDispatch.html

theTroll

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement