Polymorphic types without virtual functions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Karel Miklav

    Polymorphic types without virtual functions

    In lots of places in a programm I need to identify type of received
    messages, so I create them as virtual classes and use RTTI to find their
    type later. But these are simple messages, often without content, and I
    hate how I make their base class: by adding a dummy virtual function.

    Is there another way?

    --

    Regards,
    Karel Miklav
  • benben

    #2
    Re: Polymorphic types without virtual functions


    "Karel Miklav" <karel@lovetemp le.adbloccker.n et> wrote in message
    news:dfba2002hn c@enews2.newsgu y.com...[color=blue]
    > In lots of places in a programm I need to identify type of received
    > messages, so I create them as virtual classes and use RTTI to find their
    > type later. But these are simple messages, often without content, and I
    > hate how I make their base class: by adding a dummy virtual function.
    >
    > Is there another way?
    >
    > --
    >
    > Regards,
    > Karel Miklav[/color]

    I'm sure there are better ways other than relying on RTTI. However, before
    we know what a "message" means in your context and how it is supposed to be
    used there's not much we can help.

    Perhaps explain to us with more detail? Better still, post some code.

    Ben


    Comment

    • John Harrison

      #3
      Re: Polymorphic types without virtual functions

      Karel Miklav wrote:[color=blue]
      > In lots of places in a programm I need to identify type of received
      > messages, so I create them as virtual classes and use RTTI to find their
      > type later. But these are simple messages, often without content, and I
      > hate how I make their base class: by adding a dummy virtual function.
      >
      > Is there another way?
      >[/color]

      There no way to make a class ploymorphic without using a virtual
      function. Normally the destructor is used for this purpose, not a dummy
      function.

      class polymorphic_cas e
      {
      public:
      virtual ~polymorphic_ca se() {}
      };


      Is there are better way than using RTTI? Well that depends.

      john

      Comment

      • Andre Kostur

        #4
        Re: Polymorphic types without virtual functions

        Karel Miklav <karel@lovetemp le.adbloccker.n et> wrote in
        news:dfba2002hn c@enews2.newsgu y.com:
        [color=blue]
        > In lots of places in a programm I need to identify type of received
        > messages, so I create them as virtual classes and use RTTI to find their
        > type later. But these are simple messages, often without content, and I
        > hate how I make their base class: by adding a dummy virtual function.
        >
        > Is there another way?[/color]

        Member variable enum determining which type they are?

        Comment

        • Karel Miklav

          #5
          Re: Polymorphic types without virtual functions

          John Harrison wrote:[color=blue]
          > There no way to make a class ploymorphic without using a virtual
          > function. Normally the destructor is used for this purpose, not a dummy
          > function.
          >
          > class polymorphic_cas e
          > {
          > public:
          > virtual ~polymorphic_ca se() {}
          > };[/color]

          It'll have to do. Thanks.
          [color=blue]
          > Is there are better way than using RTTI? Well that depends.[/color]

          Shure, it's just the path of least resistance :)

          --

          Regards,
          Karel Miklav

          Comment

          • Dave Rahardja

            #6
            Re: Polymorphic types without virtual functions

            On Sat, 03 Sep 2005 06:49:48 +0200, Karel Miklav
            <karel@lovetemp le.adbloccker.n et> wrote:
            [color=blue]
            >In lots of places in a programm I need to identify type of received
            >messages, so I create them as virtual classes and use RTTI to find their
            >type later. But these are simple messages, often without content, and I
            >hate how I make their base class: by adding a dummy virtual function.
            >
            >Is there another way?[/color]

            Using RTTI to implement polymorphic behavior is usually an indication of a
            design problem. Unless you're serializing/unserializing objects, RTTI is
            seldom necessary.

            Perhaps you can explain more about the problem you are trying to solve?

            Comment

            • Karel Miklav

              #7
              Re: Polymorphic types without virtual functions

              Dave Rahardja wrote:[color=blue]
              > Using RTTI to implement polymorphic behavior is usually an indication
              > of a design problem. Unless you're serializing/unserializing objects,
              > RTTI is seldom necessary.
              >
              > Perhaps you can explain more about the problem you are trying to
              > solve?[/color]

              I have a kind of ... game. This game gets messages about UI events
              from a platform dependant layer. Messages are various but simple, like:


              class some_display_ev ent
              {
              public:

              virtual ~some_display_e vent() { };
              };

              class reconfigure_eve nt : public some_display_ev ent
              {
              public:

              int width;
              int height;

              reconfigure_eve nt(int _width, int _height) :
              width(_width), height (_height) { };

              private:

              reconfigure_eve nt();
              };

              class quit_event : public some_display_ev ent { };

              ....


              Game knows how to use the UI, but the UI knows nothing about the game;
              of course they both speak the same message-passing language. The game
              then polls the UI from time to time:


              bool loop_endlessly = true;
              while(loop_endl essly)
              {
              ...

              some_display_ev ent * event = display.check_e vents();
              if(event)
              {
              if(reconfigure_ event * re =
              dynamic_cast<re configure_event *>(event))
              {
              reconfigure(re->width, re->height);
              delete re;
              }
              else if(quit_event * qe = dynamic_cast<qu it_event *>(event))
              {
              delete qe;
              loop_endlessly = false;
              }
              else
              {
              delete event;
              throw 38122178;
              }
              }

              ...
              }


              Now this game can also draw nice things, consisting of nice and simple
              drawing primitives. These primitives are stored in containers, so they
              must be ... polymorphic. And here we go again!

              What do you say?

              --

              Regards,
              Karel Miklav

              Comment

              • Dave Rahardja

                #8
                Re: Polymorphic types without virtual functions

                On Sat, 03 Sep 2005 23:57:14 +0200, Karel Miklav
                <karel@lovetemp le.adbloccker.n et> wrote:
                [color=blue]
                >I have a kind of ... game. This game gets messages about UI events
                >from a platform dependant layer. Messages are various but simple, like:
                >
                >
                >class some_display_ev ent
                >{
                > public:
                >
                > virtual ~some_display_e vent() { };
                >};
                >
                >class reconfigure_eve nt : public some_display_ev ent
                >{
                > public:
                >
                > int width;
                > int height;
                >
                > reconfigure_eve nt(int _width, int _height) :
                > width(_width), height (_height) { };
                >
                > private:
                >
                > reconfigure_eve nt();
                >};
                >
                >class quit_event : public some_display_ev ent { };
                >
                >...
                >[/color]

                Ah, the classical polymorphic event queue problem! The use of RTTI in this
                case is not only messy (as you have discovered), it is also _very_ expensive
                in the run-time domain, as each event will take on average N/2 dynamic_cast's
                to determine what event it actually is (where N is the total number of event
                classes). If you receive several thousand messages per second (typical for a
                GUI), the lookup overhead will be significant.

                I suspect what you want is an event _interface_:

                class some_display_ev ent
                {
                public:
                virtual void do() = 0; // pure virtual
                };

                and each event will implement do() in its own intelligent way:

                class reconfigure_eve nt: public some_display_ev ent
                {
                public:
                int width;
                int height;

                reconfigure_eve nt(int width, int height);
                virtual void do();
                };

                void reconfigure_eve nt::do()
                {
                renconfigure(wi dth, height);
                }

                and your event loop will look like:

                while(loop_endl essly)
                {
                /* ... */

                some_display_ev ent* event = display.check_e vents();
                event->do();

                /* ... */
                }

                Now the overhead for processing each event is constant, i.e. one virtual
                function address lookup.

                -dr

                Comment

                • Karel Miklav

                  #9
                  Re: Polymorphic types without virtual functions

                  Dave Rahardja wrote:[color=blue]
                  > Ah, the classical polymorphic event queue problem! The use of RTTI in
                  > this case is not only messy (as you have discovered), it is also
                  > _very_ expensive in the run-time domain, as each event will take on
                  > average N/2 dynamic_cast's to determine what event it actually is
                  > (where N is the total number of event classes). If you receive
                  > several thousand messages per second (typical for a GUI), the lookup
                  > overhead will be significant.
                  >
                  > I suspect what you want is an event _interface_:
                  >
                  > class some_display_ev ent
                  > {
                  > public:
                  > virtual void do() = 0; // pure virtual
                  > };[/color]

                  Dave, thanks very much. In the mean time I've come to the same solution
                  for my other problem (graphic primitive list) and you won't believe
                  this - my interface has the same do() function :)

                  I have afterthoughts in this case as I don't want the user interface to
                  know how events are implemented but it might work if I keep the header
                  clean.

                  --

                  Regards,
                  Karel Miklav

                  Comment

                  • red floyd

                    #10
                    Re: Polymorphic types without virtual functions

                    Karel Miklav wrote:
                    [color=blue]
                    >
                    > I have afterthoughts in this case as I don't want the user interface to
                    > know how events are implemented but it might work if I keep the header
                    > clean.
                    >[/color]

                    Look into the Pimpl idiom as well. This is pretty much a wrapper around
                    a pointer, whose implementation details you want hidden.

                    Comment

                    Working...