a problem with poliporphism

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

    #16
    Re: a problem with poliporphism

    Nafai wrote:[color=blue]
    > I am going to give a more detailed example:
    >
    > // I don't type the constructors.
    >
    > class Event {
    > private:
    > int time;
    > EventType kind;
    > public:
    > enum EventType { Event1, Event2,...,Emer gency,Crime};
    > int when() {return time; }
    > EventType what() { return kind; }
    > }
    >
    > class Emergency : public Event {
    > private:
    > int area;
    > public:
    > int where() {return area;}
    > };
    >
    > class Crime : public Event {
    > private:
    > string person;
    > int aCrime;.
    > public:
    > string who() { return person; }
    > int whatHeDid() { return aCrime; }
    > };
    >
    > void doSomethingWith Events(Event* pE)
    > {
    > switch(pE->kind) {
    > case Event::Emergenc y : callAmbulance(p E->where(),pE->when());
    > break;
    > case Event::Crime: blame(pE->who(),pE->whatHeDid(), pE->when());
    > break;
    > case Event::Event1 : doSomethingRela tedToEvent1(pE->when()); break;
    > ...
    > }
    > }
    >
    > int main() {
    > list<Event*> lst;
    > .... // insert somehow Events in lst
    > Event* pEvt = lst.first();
    > lst.pop_first() ;
    > doSomethingWith Event(pEvt);
    > ....
    > }
    >
    >
    > My question is: which is the best way to do that? Is it OK like before?[/color]

    In case it's not an oversight on your part, I just want to point out
    that you should add a virtual destructor to your Event class. Even if
    it's an empty *noop* you should still add it.

    KPB







    Comment

    • Nafai

      #17
      Re: a problem with poliporphism

      "KPB" <k@w.net> escribió en el mensaje
      news:vNSAd.2577 3$EH1.11348@fe1 0.lga...[color=blue]
      > Nafai wrote:[color=green]
      >> I am going to give a more detailed example:
      >>
      >> // I don't type the constructors.
      >>
      >> class Event {
      >> private:
      >> int time;
      >> EventType kind;
      >> public:
      >> enum EventType { Event1, Event2,...,Emer gency,Crime};
      >> int when() {return time; }
      >> EventType what() { return kind; }
      >> }
      >>
      >> class Emergency : public Event {
      >> private:
      >> int area;
      >> public:
      >> int where() {return area;}
      >> };
      >>
      >> class Crime : public Event {
      >> private:
      >> string person;
      >> int aCrime;.
      >> public:
      >> string who() { return person; }
      >> int whatHeDid() { return aCrime; }
      >> };
      >>
      >> void doSomethingWith Events(Event* pE)
      >> {
      >> switch(pE->kind) {
      >> case Event::Emergenc y : callAmbulance(p E->where(),pE->when());
      >> break;
      >> case Event::Crime: blame(pE->who(),pE->whatHeDid(), pE->when());
      >> break;
      >> case Event::Event1 : doSomethingRela tedToEvent1(pE->when());
      >> break;
      >> ...
      >> }
      >> }
      >>
      >> int main() {
      >> list<Event*> lst;
      >> .... // insert somehow Events in lst
      >> Event* pEvt = lst.first();
      >> lst.pop_first() ;
      >> doSomethingWith Event(pEvt);
      >> ....
      >> }
      >>
      >>
      >> My question is: which is the best way to do that? Is it OK like before?[/color]
      >
      > In case it's not an oversight on your part, I just want to point out that
      > you should add a virtual destructor to your Event class. Even if it's an
      > empty *noop* you should still add it.
      >
      > KPB
      >[/color]

      OK.

      But do you think that is a good desing? How could it be done better?


      Comment

      • Jonathan Mcdougall

        #18
        Re: a problem with poliporphism

        Nafai wrote:[color=blue]
        > I am going to give a more detailed example:
        >
        > // I don't type the constructors.
        >
        > class Event {
        > private:
        > int time;
        > EventType kind;
        > public:
        > enum EventType { Event1, Event2,...,Emer gency,Crime};
        > int when() {return time; }
        > EventType what() { return kind; }[/color]

        Event is meant to be used as a base class and does
        not have a virtual destructor nor virtual
        functions. What kind of base class is that?
        [color=blue]
        > }
        >
        > class Emergency : public Event {
        > private:
        > int area;
        > public:
        > int where() {return area;}
        > };
        >
        > class Crime : public Event {
        > private:
        > string person;
        > int aCrime;.
        > public:
        > string who() { return person; }
        > int whatHeDid() { return aCrime; }
        > };
        >
        >
        > void doSomethingWith Events(Event* pE)
        > {
        > switch(pE->kind) {
        > case Event::Emergenc y : callAmbulance(p E->where(),pE->when());
        > break;
        > case Event::Crime: blame(pE->who(),pE->whatHeDid(), pE->when());
        > break;
        > case Event::Event1 : doSomethingRela tedToEvent1(pE->when()); break;
        > ...
        > }
        > }[/color]

        That is not recommended. You seem not to
        understand the use of polymorphism and public
        inheritance.

        Public inheritance has many uses, but in your
        case, it is a simple case of interface<->behavior.
        The base class specifies an interface (with
        [pure] virtual functions) and derived classes
        specify the behavior.

        class Event
        {
        public:
        virtual ~Event();

        virtual void process() = 0; // that's the
        // interface
        };

        class Emergency : public Event
        {
        private:
        void call_ambulance( );

        public:
        virtual void process() // that's a behavior
        {
        call_ambulance( );
        }
        };

        class Crime : public Event
        {
        private:
        void blame();

        public:
        virtual void process()
        {
        blame(); // that's another behavior
        }
        };


        typedef std::sector<Eve nt*> Events;

        void f(Events &events)
        {
        for (Events::iterat or itor=events.beg in();
        itor!=events.en d();
        ++itor)
        {
        Event *e = *itor;
        e->process(); // calls the correct
        // process()
        }
        }


        Jonathan

        Comment

        • Nafai

          #19
          Re: a problem with poliporphism

          KPB escribió:[color=blue]
          > Nafai wrote:
          >[color=green]
          >> Do you think it is a good a idea to do this:
          >> void doSomethingWith Events(Event* pE)
          >> {
          >> Emergency* pEmergency;
          >> switch(pE->kind) {
          >> case Event::Emergenc y :
          >> pEmergency=dyna mic_cast<Emerge ncy*>(pE);
          >> callAmbulance(p Emergency->where(), pEmergency->when());
          >> break;
          >> ... // and so on
          >> }
          >> }[/color]
          >
          >
          > No. That leads me to another point on your classes. What's the point in
          > having polimorphism if the specific kind of event is stored as some
          > internal value of the Event class? Every time you add a new class, you
          > have to update your Event class to deal with a new "kind" enumeration.
          >
          > So, with your current design, when you derive a class from Event, you
          > also have to modify the Event class. Not good design.
          >
          > Ditch the enum list in Event.
          >
          > KPB
          >[/color]

          OK. So what desing would be the best in your opinion? How would you
          solve that problem?

          Comment

          • KPB

            #20
            Re: a problem with poliporphism

            Nafai wrote:[color=blue]
            > KPB escribió:
            >[color=green]
            >> Nafai wrote:
            >>[color=darkred]
            >>> Do you think it is a good a idea to do this:
            >>> void doSomethingWith Events(Event* pE)
            >>> {
            >>> Emergency* pEmergency;
            >>> switch(pE->kind) {
            >>> case Event::Emergenc y :
            >>> pEmergency=dyna mic_cast<Emerge ncy*>(pE);
            >>> callAmbulance(p Emergency->where(), pEmergency->when());
            >>> break;
            >>> ... // and so on
            >>> }
            >>> }[/color]
            >>
            >>
            >>
            >> No. That leads me to another point on your classes. What's the point
            >> in having polimorphism if the specific kind of event is stored as some
            >> internal value of the Event class? Every time you add a new class, you
            >> have to update your Event class to deal with a new "kind" enumeration.
            >>
            >> So, with your current design, when you derive a class from Event, you
            >> also have to modify the Event class. Not good design.
            >>
            >> Ditch the enum list in Event.
            >>
            >> KPB
            >>[/color]
            >
            > OK. So what desing would be the best in your opinion? How would you
            > solve that problem?[/color]


            I've told you quite a bit about what I'd do.

            I'm sorry but I think you need to study the topic of inheritence a
            little better.

            KPB

            Comment

            • Nafai

              #21
              Re: a problem with poliporphism

              KPB escribió:[color=blue]
              > Nafai wrote:
              >[color=green]
              >> KPB escribió:
              >>[color=darkred]
              >>> Nafai wrote:
              >>>
              >>>> Do you think it is a good a idea to do this:
              >>>> void doSomethingWith Events(Event* pE)
              >>>> {
              >>>> Emergency* pEmergency;
              >>>> switch(pE->kind) {
              >>>> case Event::Emergenc y :
              >>>> pEmergency=dyna mic_cast<Emerge ncy*>(pE);
              >>>> callAmbulance(p Emergency->where(), pEmergency->when());
              >>>> break;
              >>>> ... // and so on
              >>>> }
              >>>> }
              >>>
              >>>
              >>>
              >>>
              >>> No. That leads me to another point on your classes. What's the point
              >>> in having polimorphism if the specific kind of event is stored as
              >>> some internal value of the Event class? Every time you add a new
              >>> class, you have to update your Event class to deal with a new "kind"
              >>> enumeration.
              >>>
              >>> So, with your current design, when you derive a class from Event, you
              >>> also have to modify the Event class. Not good design.
              >>>
              >>> Ditch the enum list in Event.
              >>>
              >>> KPB
              >>>[/color]
              >>
              >> OK. So what desing would be the best in your opinion? How would you
              >> solve that problem?[/color]
              >
              >
              >
              > I've told you quite a bit about what I'd do.
              >
              > I'm sorry but I think you need to study the topic of inheritence a
              > little better.
              >
              > KPB[/color]

              Just tell me an outline of your solution. I know what it is polymorphism
              and what is inheritance. Please, just tell me your solution. If you have it.

              Comment

              • Jeff Flinn

                #22
                Re: a problem with poliporphism

                Nafai wrote:[color=blue]
                > KPB escribió:[color=green]
                >> Nafai wrote:[color=darkred]
                >>> KPB escribió:
                >>>> Nafai wrote:[/color][/color][/color]

                ....
                [color=blue]
                > Just tell me an outline of your solution. I know what it is
                > polymorphism and what is inheritance. Please, just tell me your
                > solution. If you have it.[/color]

                You've been told a few times by a few people already. Give it your best
                shot, post your try here and you'll get some help.

                Jeff


                Comment

                • Nafai

                  #23
                  Re: a problem with poliporphism


                  "Jonathan Mcdougall" <jonathanmcdoug all@DELyahoo.ca > escribió en el mensaje
                  news:UOWAd.33$a z2.83455@weber. videotron.net.. .[color=blue]
                  > Nafai wrote:[color=green]
                  >> I am going to give a more detailed example:
                  >>
                  >> // I don't type the constructors.
                  >>
                  >> class Event {
                  >> private:
                  >> int time;
                  >> EventType kind;
                  >> public:
                  >> enum EventType { Event1, Event2,...,Emer gency,Crime};
                  >> int when() {return time; }
                  >> EventType what() { return kind; }[/color]
                  >
                  > Event is meant to be used as a base class and does not have a virtual
                  > destructor nor virtual functions. What kind of base class is that?
                  >[color=green]
                  >> }
                  >>
                  >> class Emergency : public Event {
                  >> private:
                  >> int area;
                  >> public:
                  >> int where() {return area;}
                  >> };
                  >>
                  >> class Crime : public Event {
                  >> private:
                  >> string person;
                  >> int aCrime;.
                  >> public:
                  >> string who() { return person; }
                  >> int whatHeDid() { return aCrime; }
                  >> };
                  > >
                  > >
                  >> void doSomethingWith Events(Event* pE)
                  >> {
                  >> switch(pE->kind) {
                  >> case Event::Emergenc y : callAmbulance(p E->where(),pE->when());
                  >> break;
                  >> case Event::Crime: blame(pE->who(),pE->whatHeDid(), pE->when());
                  >> break;
                  >> case Event::Event1 : doSomethingRela tedToEvent1(pE->when());
                  >> break;
                  >> ...
                  >> }
                  >> }[/color]
                  >
                  > That is not recommended. You seem not to understand the use of
                  > polymorphism and public inheritance.
                  >
                  > Public inheritance has many uses, but in your case, it is a simple case of
                  > interface<->behavior. The base class specifies an interface (with [pure]
                  > virtual functions) and derived classes specify the behavior.
                  >
                  > class Event
                  > {
                  > public:
                  > virtual ~Event();
                  >
                  > virtual void process() = 0; // that's the
                  > // interface
                  > };
                  >
                  > class Emergency : public Event
                  > {
                  > private:
                  > void call_ambulance( );
                  >
                  > public:
                  > virtual void process() // that's a behavior
                  > {
                  > call_ambulance( );
                  > }
                  > };
                  >
                  > class Crime : public Event
                  > {
                  > private:
                  > void blame();
                  >
                  > public:
                  > virtual void process()
                  > {
                  > blame(); // that's another behavior
                  > }
                  > };
                  >
                  >
                  > typedef std::sector<Eve nt*> Events;
                  >
                  > void f(Events &events)
                  > {
                  > for (Events::iterat or itor=events.beg in();
                  > itor!=events.en d();
                  > ++itor)
                  > {
                  > Event *e = *itor;
                  > e->process(); // calls the correct
                  > // process()
                  > }
                  > }
                  >
                  >
                  > Jonathan[/color]


                  That's OK, but I can't do that. If I could of course I would have. The
                  "process()" is done by another class. That is: I DO NEED to take "area",
                  "person" etc with where(), who() etc. There's no way to change this.


                  Comment

                  • Jonathan Mcdougall

                    #24
                    Re: a problem with poliporphism

                    Nafai wrote:[color=blue]
                    >
                    > That's OK, but I can't do that. If I could of course I would have. The
                    > "process()" is done by another class. That is: I DO NEED to take "area",
                    > "person" etc with where(), who() etc. There's no way to change this.[/color]

                    If you can't have virtual functions, you need to
                    emulate them either by using an id-switch (as you
                    did) or a type switch with dynamic_cast.

                    void f(Event *event)
                    {
                    if ( Emergency *e =
                    dynamic_cast<Em ergency*>(event ) )
                    {
                    }
                    else if ( Crime *c =
                    dynamic_cast<Cr ime*>(event) )
                    {
                    }
                    }

                    But that means f() must know about all the
                    subtypes and must test from down to top of the
                    hierarchy. That's a pain and it's ugly, but you
                    may have no choice.


                    Jonathan

                    Comment

                    • Mike Hewson

                      #25
                      Re: a problem with poliporphism [OT]

                      Victor Bazarov wrote:[color=blue]
                      > "E. Robert Tisdale" <E.Robert.Tisda le@jpl.nasa.gov > wrote...
                      >[color=green]
                      >>Nafai wrote:
                      >>
                      >>[snip]
                      >>
                      >>What is poliporphism?[/color]
                      >
                      >
                      > Pinch your nose and try saying "polyMorphi sm". Whaddya get?
                      >
                      >[/color]
                      For me, alas, a fart. :-)
                      Seriously, it's a cross between a parrot widget and a dolphin thingy.

                      --

                      Cheers
                      --
                      Hewson::Mike
                      "This letter is longer than usual because I lack the time to make it
                      shorter" - Blaise Pascal

                      Comment

                      • Howard

                        #26
                        Re: a problem with poliporphism


                        "Nafai" <nafai3000@yaho o.es> wrote in message
                        news:D81Bd.1003 23$oN1.169983@t elenews.telelin e.es...
                        [color=blue][color=green]
                        >> class Event
                        >> {
                        >> public:
                        >> virtual ~Event();
                        >>
                        >> virtual void process() = 0; // that's the
                        >> // interface
                        >> };
                        >>
                        >> class Emergency : public Event
                        >> {
                        >> private:
                        >> void call_ambulance( );
                        >>
                        >> public:
                        >> virtual void process() // that's a behavior
                        >> {
                        >> call_ambulance( );
                        >> }
                        >> };
                        >>
                        >> class Crime : public Event
                        >> {
                        >> private:
                        >> void blame();
                        >>
                        >> public:
                        >> virtual void process()
                        >> {
                        >> blame(); // that's another behavior
                        >> }
                        >> };
                        >>
                        >>
                        >> typedef std::sector<Eve nt*> Events;
                        >>
                        >> void f(Events &events)
                        >> {
                        >> for (Events::iterat or itor=events.beg in();
                        >> itor!=events.en d();
                        >> ++itor)
                        >> {
                        >> Event *e = *itor;
                        >> e->process(); // calls the correct
                        >> // process()
                        >> }
                        >> }
                        >>
                        >>
                        >> Jonathan[/color]
                        >
                        >
                        > That's OK, but I can't do that. If I could of course I would have. The
                        > "process()" is done by another class. That is: I DO NEED to take "area",
                        > "person" etc with where(), who() etc. There's no way to change this.[/color]


                        How about passing a pointer to the instance of the class that will handle
                        the process() call? Or, perhaps better, make the pointer a member of the
                        Event class, and initialize it when creating the Event objects? Like
                        this...


                        // forward declared, so pointer can be used here
                        class ProcessClass;

                        class Event
                        {
                        ProcessClass* pProcessor;

                        public:
                        Event( ProcessClass* theProcessor ) : pProcessor(theP rocessor);

                        virtual ~Event();

                        virtual void process() = 0; // that's the
                        // interface
                        };

                        class Emergency : public Event
                        {
                        public:
                        virtual void process() // that's a behavior
                        {
                        pProcessor->call_ambulance (where(),when() );
                        }
                        };

                        class Crime : public Event
                        {
                        public:
                        virtual void process()
                        {
                        pProcessor->blame(who(),wh atHeDid(),when( )); // that's
                        another behavior
                        }
                        };


                        typedef std::sector<Eve nt*> Events;

                        void f(Events &events)
                        {
                        for (Events::iterat or itor=events.beg in();
                        itor!=events.en d();
                        ++itor)
                        {
                        Event *e = *itor;
                        e->process(); // calls the correct
                        // process()
                        }
                        }

                        I haven't compiled this, just modified what Jonathon wrote, and I haven't
                        added back in the functions who(), where(), etc., but you can do that
                        yourself. Does this concept make sense now?

                        -Howard



                        Comment

                        Working...